0% found this document useful (0 votes)
30 views21 pages

Wa0034.

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views21 pages

Wa0034.

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

Chapter-2

Searching and Sorting


Sorting:-
Sorting refers to arranging data in a particular format. Sorting algorithm specifies the way to
arrange data in a particular order. Most common orders are in numerical or lexicographical order.

The importance of sorting lies in the fact that data searching can be optimized to a very high level,
if data is stored in a sorted manner. Sorting is also used to represent data in more readable formats.
Following are some of the examples of sorting in real-life scenarios −

• Telephone Directory − the telephone directory stores the telephone numbers of people
sorted by their names, so that the names can be searched easily.

• Dictionary − the dictionary stores words in an alphabetical order so that searching of any
word becomes easy.

The sorting is classified into two categories:

1) Internal sorting (In-place sorting):

Sorting algorithms may require some extra space for comparison and temporary storage of few
data elements. These algorithms do not require any extra space (in memory) and sorting is
said to happen in-place called as internal sorting. For example, within the array itself.
This is called in-place sorting.

Bubble sort, insertion sort, selection sort is an example of internal sorting.

2) External sorting( Not-In-place sorting):


When the data to be sorted can’t be accommodated in the main memory at the same time
then same data is kept in auxiliary (secondary) memory (Hard disk, floppy disk) called as
External sorting.
For example: Merge-sort, Radix sort

[https://www.tutorialspoint.com/data_structures_algorithms]

Sorting Efficiency
There are many techniques for sorting. Implementation of particular sorting technique depends upon
situation. Sorting techniques mainly depends on two parameters. First parameter is the execution
time of program, which means time taken for execution of program. Second is the space, which
means space, taken by the program?
Sorting Techniques
List sorting techniques?

1. Selection sort
2. Insertion sort
3. Bubble sort
4. Radix sort
5. Quick sort

1. Selection sort
Selection sorting is conceptually the most simplest sorting algorithm. This algorithm first finds
the smallest element in the array and exchanges it with the element in the first position, then find the
second smallest element and exchange it with the element in the second position, and continues in
this way until the entire array is sorted.
How Selection Sorting Works

In the first pass, the smallest element found is 1, so it is placed at the first position, then leaving first
element, smallest element is searched from the rest of the elements, 3 is the smallest, so it is then
placed at the second position. Then we leave 1 and 3, from the rest of the elements, we search for the
smallest and put it at third position and keep doing this, until array is sorted.
Sorting using Selection Sort Algorithm

Step 1 − Set MIN to location 0


Step 2 − Search the minimum element in the list
Step 3 − Swap with value at location MIN
Step 4 − Increment MIN to point to next element
Step 5 − Repeat until list is sorted

WAP to sort the elements using selection sort


#include <stdio.h>
void main()
{
int array[100], n, i, j, min, swap;
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for ( i = 0 ; i < n ; i++ )
scanf("%d", &array[i]);
i=o
while(i<n)
{
min = a[i];
for(j=i+1; j < 5; j++)
{
if(min > a[j])
{
min = a[j];
temp = a[i];
a[i] = a[j];
a[j] =temp;
}
}
i++;
}
printf("Sorted list in ascending order:\n");
for ( i = 0 ; i < n ; i++ )
printf("%d\n", array[i]);
}

Advantages
i. The main advantage of the selection sort is that it performs well on a small list.
ii. It is an in-place sorting algorithm; no additional temporary storage is required beyond
what is needed to hold the original list.

Disadvantages
i. The primary disadvantage of the selection sort is its poor efficiency when dealing with a huge list
of items.
ii. Its performance is easily influenced by the initial ordering of the items before the sorting process.
Complexity Analysis of Selection Sorting
Worst case time complexity: O(n2)
Best case time complexity: O(n2)
Average case time complexity: O(n2)
Space complexity: O(1)
2. Insertion sort:
It is a simple Sorting algorithm which sorts the array by shifting elements one by one. Following
are some of the important characteristics of Insertion Sort.

1. It has one of the simplest implementation


2. It is efficient for smaller data sets, but very inefficient for larger lists.
3. Insertion Sort is adaptive, that means it reduces its total number of steps if given a partially
sorted list, hence it increases its efficiency.
4. It is better than Selection Sort and Bubble Sort algorithms.
5. Its space complexity is less, like Bubble Sorting, inerstion sort also requires a single additional
memory space.
6. It is Stable, as it does not change the relative order of elements with equal keys

How Insertion Sorting Works


Insertion Sort Algorithm:
Step 1 −
If it is the first element, it is already sorted. return 1;
Step 2 −
Pick next element
Step 3 −
Compare with all elements in the sorted sub-list
Step 4 −
Shift all the elements in the sorted sub-list that is greater than the
value to be sorted
Step 5 − Insert the value
Step 6 − Repeat until list is sorted

WAP for Insertion sort


/* insertion sort ascending order */

#include <stdio.h>

int main()
{
int n, array[1000], c, d, t;

printf("Enter number of elements\n");


scanf("%d", &n);

printf("Enter %d integers\n", n);

for (c = 0; c < n; c++) {


scanf("%d", &array[c]);
}

for (c = 1 ; c <= n - 1; c++) {


d = c;

while ( d > 0 && array[d] < array[d-1]) {


t = array[d];
array[d] = array[d-1];
array[d-1] = t;
d--;
}
}

printf("Sorted list in ascending order:\n");

for (c = 0; c <= n - 1; c++) {


printf("%d\n", array[c]);
}

return 0;
}
Advantages of insertion sort:
1. simplicity and efficiency of the insertion sort, especially for small arrays.
Disadvantages of insertion sort:
1. It is less efficient on list containing more number of elements.
2. As the number of elements increases the performance of the program would be slow.
3. Insertion sort needs a large number of element shifts.
Complexity Analysis of Selection Sorting
Worst case time complexity: O(n2)
Best case time complexity: O(n)
Average case time complexity: O(n2)
Space complexity: O(1)
3) Bubble Sort
Bubble sort is a simple sorting algorithm. This sorting algorithm is comparison-based algorithm
in which each pair of adjacent elements is compared and the elements are swapped if they are
not in order. This algorithm is not suitable for large data sets as its average and worst case
complexity are of Ο(n2) where n is the number of items.
How Bubble sort works
We take an unsorted array for our example. Bubble sort takes Ο(n 2) time so we're keeping it short
and precise.

Bubble sort starts with very first two elements, comparing them to check which one is greater.

In this case, value 33 is greater than 14, so it is already in sorted locations. Next, we compare 33
with 27.

We find that 27 is smaller than 33 and these two values must be swapped.

The new array should look like this −

Next we compare 33 and 35. We find that both are in already sorted positions.

Then we move to the next two values, 35 and 10.


We know then that 10 is smaller 35. Hence they are not sorted.

We swap these values. We find that we have reached the end of the array. After one iteration,
the array should look like this −

To be precise, we are now showing how an array should look like after each iteration. After the
second iteration, it should look like this −

Notice that after each iteration, at least one value moves at the end.

And when there's no swap required, bubble sorts learns that an array is completely sorted.

Bubble Sort Algorithm:


We assume list is an array of n elements. We further assume that swap function swaps the values of
the given array elements.

begin BubbleSort(list)
for all elements of list
if list[i] > list[i+1]
swap(list[i], list[i+1])
end if
end for
return list
end BubbleSort

Advantages
i. The bubble sort requires very little memory other than that which the array or list itself occupies.
ii. The bubble sort is comprised of relatively few lines of code.
iii. With a best-case running time of O(n), the bubble sort is good for testing whether or not a list is
sorted or not. Other sorting methods often cycle through their whole sorting sequence, which often
have running times of O(n^2) or O(n log n) for this task.
iv. The same applies for data sets that have only a few items that need to be swapped a few times.

Disadvantages
i. The main disadvantage of the bubble sort method is the time it requires.
ii. With a running time of O (n^2), it is highly inefficient for large data sets.

WAP to sort the elements in the array using bubble sort.


#include <stdio.h>
int main()
{
int array[100], n, i, j, temp;
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for (i = 0; j < n; i++)
scanf("%d", &array[i]);
for (i = 0 ; i < ( n - 1 ); i++)
{
for (j = i+1 ; j < n; j++)
{
if (array[i] > array[j]) /* For decreasing order use < */
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
printf("Sorted list in ascending order:\n");
for ( c = 0 ; c < n ; c++ )
printf("%d\n", array[c]);
return 0;
}
Complexity Analysis of Bubble Sorting
In Bubble Sort, n-1 comparisons will be done in 1st pass, n-2 in 2nd pass, n-3 in 3rd pass and so on.
So the total number of comparisons will be
(n-1)+(n-2)+(n-3)+.....+3+2+1
Sum = n(n-1)/2
i.e O(n2)
Hence the complexity of Bubble Sort is O(n2).
The main advantage of Bubble Sort is the simplicity of the algorithm. Space complexity for Bubble
Sort is O(1), because only single additional memory space is required for temp variable
Best-case Time Complexity will be O(n), it is when the list is already sorted.
[http://www.studytonight.com/data-structures/bubble-sort]
4) Radix Sort
It is also known as bucket sort.
The array for the bucket sort is divided in to 10 buckets from 0 to 9. This sort is commonly also
known as bucket sort. The numbers are sorted on the LSB (Least Significant Bit) of any
number for the first pass.

Example: Assume the input array is:


10,21,17,34,44,11,654,123
Based on the algorithm, we will sort the input array according to the one's digit (least significant
digit).
0: 10
1: 21 11
2:
3: 123
4: 34 44 654
5:
6:
7: 17
8:
9:

So, the array becomes 10,21,11,123,34,44,654,17


Now, we'll sort according to the ten's digit:
0:
1: 10 11 17
2: 21 123
3: 34
4: 44
5: 654
6:
7:
8:
9:

Now, the array becomes : 10,11,17,21,123,34,44,654


Finally , we sort according to the hundred's digit (most significant digit):
0: 010 011 017 021 034 044
1: 123
2:
3:
4:
5:
6: 654
7:
8:
9:

The array becomes : 10,11,17,21,34,44,123,654 which is sorted. This is how our algorithm works.

Advantages:
1.Fast when the keys are short i.e. when the range of the array elements is less.
2. Used in suffix array construction.
Disadvantages:
1. Since Radix Sort depends on digits or letters, Radix Sort is much less flexible than other sorts.
Hence, for every different type of data it needs to be rewritten.
2. The constant for Radix sort is greater compared to other sorting algorithms.
3. It takes more space compared to Quicksort which is inplace sorting.

5) Quick Sort:
Quick Sort, as the name suggests, sorts any list very quickly. Quick sort is not stable search, but it is
very fast and requires very less additional space. It is based on the rule of Divide and Conquer (also
called partition-exchange sort). This algorithm divides the list into three main parts:

1. Elements less than the Pivot element


2. Pivot element
3. Elements greater than the pivot element

In the list of elements, mentioned in below example, we have taken 25 as pivot. So after the first
pass, the list will be changed like this.
6 8 17 14 25 63 37 52
Hence after the first pass, pivot will be set at its position, with all the elements smaller to it on its left
and all the elements larger than it on the right. Now 6 8 17 14 and 63 37 52 are considered as two
separate lists, and same logic is applied on them, and we keep doing this until the complete list is
sorted.
How Quick Sorting Works
Quick Sort Pivot Algorithm
In Quick sort algorithm, partitioning of the list is performed using following steps...

Step 1 - Consider the first element of the list as pivot (i.e., Element at first position in the list).

Step 2 - Define two variables i and j. Set i and j to first and last elements of the list respectively.

Step 3 - Increment i until list[i] > pivot then stop.

Step 4 - Decrement j until list[j] < pivot then stop.

Step 5 - If i < j then exchange list[i] and list[j].

Step 6 - Repeat steps 3, 4 & 5 until i > j.

Step 7 - Exchange the pivot element with list[j] element.

Advantages:

o One of the fastest algorithms on average.


o Does not need additional memory (the sorting takes place in the array - this is
called in-place processing). Compare with mergesort: mergesort needs additional
memory for merging.
Disadvantages: The worst-case complexity is O(N2)

Applications:

Commercial applications use Quicksort - generally it runs fast, no additional memory,


this compensates for the rare occasions when it runs with O(N2)

Never use in applications which require guaranteed response time:

o Life-critical (medical monitoring, life support in aircraft and space craft)


o Mission-critical (monitoring and control in industrial and research plants
handling dangerous materials, control for aircraft, defense, etc)

Complexity Analysis of Quick Sort


Worst case time complexity: O (n2)
Best case time complexity: O (n log n)
Average case time complexity: O (n log n)
Space complexity: O (n log n)

• Space required by quick sort is very less, only O(n log n) additional space is required.
• Quick sort is not a stable sorting technique, so it might change the occurrence of two similar
elements in the list while sorting.

2.2 Searching

Search is a process of finding a value in a list of values. In other words, searching is the process of
locating given value position in a list of values.

There are 2 types of searching:

1) Linear Search/Sequential Search


2) Binary Search
Linear Search/Sequential Search

Linear search algorithm finds given element in a list of elements with O(n) time complexity
where n is total number of elements in the list. This search process starts comparing of search
element with the first element in the list. If both are matching then results with element found
otherwise search element is compared with next element in the list. If both are matched, then the
result is "element found". Otherwise, repeat the same with the next element in the list until search
element is compared with last element in the list, if that last element also doesn't match, then the
result is "Element not found in the list".

1. Linear Search for Sorted List:


The efficiency of linear search can be increased if we take a previously sorted array say in ascending order. Now
in this case, the basic algorithm remains the same as we have done in case of an unsorted array but the only
difference is we do not have to search the entire array every time. Whenever we encounter an element say y
greater than the key to be searched, we conclude that there is no such element which is equal to the key, in the list.
This is because all the elements in the list are in ascending order and all elements to the right of y will be greater
or equal to y, ie greater than the key. So there is no point in continuing the search even if the end of the list has not
been reached and the required element has not been found.
Linear search( int x[], int n, int key)
{
int i, flag=0;
for(i=0; i < n && x[i] <= key; i++)
{
if(x[i]==key)
{
flag=1;
break;
}
}
if(flag==1) /* Unsuccessful Search*/
return(-1);
else return(1); /*Successful search*/
}

Example
Consider the following list of element and search element...
The array to be sorted is as follows:
21 35 41 65 72
It is sorted in ascending order. Now let key = 40. At first 21 is checked as x[0]=21.
It is smaller than 40. So next element is checked which is 35 that is also smaller than 40. So now 41 is checked.
But 41 > 40 & all elements to the right of 41 are also greater than 40.So we terminate the search as an
unsuccessful one and we may not have to search the entire list.
Complexity:

Searching is NOT more efficient when key is in present in the list in case when the search key value lies between
the minimum and the maximum element in the list. The Complexity of linear search both in case of sorted and
unsorted list is the same. The average complexity for linear search for sorted list is better than that in unsorted list
since the search need not continue beyond an element with higher value than the search value.

Linear Search for Unsorted List:

In case of unsorted list, we have to search the entire list every time i.e.we have to keep on searching the list till
we find the required element or we reach the end of the list.this is because as elements are not in any order,so any
element can be found just anywhere.

Algorithm:

linear search(int x[],int n,int key)


{
int i,flag = 0;
for(i=0;i < n ; i++)
{
if(x[i]==key)
{
flag=1;
break;
}
}
if(flag==0)
return(-1);
else
return(1);
}

Complexity:

The number of comparisons in this case is n-1.So it is of o(n). The implementation af algo is simple but the
efficiency is not good. Every time we have to search the whole array(if the element with required value is not
found out).

Program for Linear Search:

#include<stdio.h>
#include<conio.h>

void main(){
int list[20],size,i,sElement;
printf("Enter size of the list: ");
scanf("%d",&size);

printf("Enter any %d integer values: ",size);


for(i = 0; i < size; i++)
scanf("%d",&list[i]);

printf("Enter the element to be Search: ");


scanf("%d",&sElement);

// Linear Search Logic


for(i = 0; i < size; i++)
{
if(sElement == list[i])
{
printf("Element is found at %d index", i);
break;
}
}
if(i == size)
printf("Given element is not found in the list!!!");
getch();
}

Advantage
i. This is the simplest searching algorithm
ii. The space complexity is very less.
iii. Efficient for small data, if the dataset created is small.

Disadvantage
i. The time complexity increases.
ii. The number of comparisons become large as n, for the large set of array.
2. Binary Search:

The most efficient method of searching a sequential file is binary search. This method is applicable
to elements of a sorted list only. In this method, to search an element we compare it with the center
element of the list. If it matches, then the search is successful and it is terminated. But if it does not
match, the list is divided into two halves. The first half consists of 0th element to the center element
whereas the second list consists of the element next to the center element to the last element. Now It
is obvious that all elements in first half will be < or = to the center element and all element elements
in the second half will be > than the center element. If the element to be searched is greater than the
center element then searching will be done in the second half, otherwise in the first half.

Same process of comparing the element to be searched with the center element & if not found then
dividing the elements into two halves is repeated for the first or second half. This process is
repeated till the required element is found or the division of half parts gives a single element.

Algorithm for Binary Search.

Illustrative Explanation:
Let the array to be sorted is as follows:

11 23 31 33 65 68 71 89 100

Now let the element to be searched ie key = 31 At first hi=8 low=0

so mid=4 and x[mid]= 65 is the center element but 65 > 31.

So now hi = (mid-1) i.e. 4-1=3.

Now mid= (0 + 3)/2 = 1, so x[mid]= 23 < 31.

So again low= 1 + 1 = 2.

Now mid = (3 + 2)/2 = 2 & x[mid]= 31 = key. So the search is successful.

Similarly had the key been 32 it would have been an unsuccessful search.

WAP to search the element in the array using binary search


#include <stdio.h>
void main ()
{
int c, first, last, middle, n, search, array[100];
printf("Enter number of elements\n");
scanf("%d",&n);
printf("Enter %d integers\n", n);
for (c = 0; c < n; c++)
scanf("%d",&array[c]);
printf("Enter value to find\n");
scanf("%d", &search);
first = 0;
last = n - 1;
middle = (first+last)/2;
while (first <= last) {
if (array[middle] < search)
first = middle + 1;
else if (array[middle] == search) {
printf("%d found at location %d.\n", search, middle+1);
break;
}
else
last = middle - 1;
middle = (first + last)/2;
}
if (first > last)

printf("Not found! %d is not present in the list.\n", search);

Complexity:

This is highly efficient than linear search. Each comparison in the binary search reduces the no. of possible
candidates by a factor of 2. So the maximum no. of key comparisons is equal to log(2,n) approx. So the complexity
of binary search is O(log n).

Limitations:

Binary search algorithm can only be used if the list to be searched is in array form and not linked list. This is
bcause the algorithm uses the fact that the indices of the array elements are consecutive integers. This makes this alg
orithm useless for lists with many insertions and deletions which can be implemented only when the list is in the form
of a linked list.

[referred from NPTEL: http://nptel.ac.in/courses/106103069/44]

Program in C Programming Language

You might also like