0% found this document useful (0 votes)
5 views27 pages

Searching and Sorting.docx

The document discusses various sorting algorithms, including Bubble Sort, Insertion Sort, Selection Sort, and Shell Sort, explaining their techniques and algorithms. It highlights the importance of sorting for optimizing data searching and presents examples for each sorting method. Additionally, it covers efficiency parameters and complexity functions for understanding the performance of these algorithms.

Uploaded by

keerthi9643
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)
5 views27 pages

Searching and Sorting.docx

The document discusses various sorting algorithms, including Bubble Sort, Insertion Sort, Selection Sort, and Shell Sort, explaining their techniques and algorithms. It highlights the importance of sorting for optimizing data searching and presents examples for each sorting method. Additionally, it covers efficiency parameters and complexity functions for understanding the performance of these algorithms.

Uploaded by

keerthi9643
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/ 27

age | 1

Unit 4: 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.

Increasing Order:
A sequence of values is said to be in increasing order, if the successive element is greater
than the previous one. For example, 1, 3, 4, 6, 8, 9 are in increasing order, as every next
element is greater than the previous element.
Decreasing Order:
A sequence of values is said to be in decreasing order, if the successive element is less than
the current one. For example, 9, 8, 6, 4, 3, 1 are in decreasing order, as every next element
is less than the previous element.

Efficiency parameters:
This sorting method that is to be implemented depends on how it behaves in each situation.
For a given problem, it is important to know which method will be best suited.
Some parameters:
​ Execution time: it is the time required for the execution of the program.
​ Space or Memory: it is the amount of space required to store data or variables.
​ Coding time: it is the time required to develop a sorting technique for the given
problems.
Complexity function f(n):
It is the function which gives the running time of the algorithm in terms of size of the input
data ‘n’.
There are 3 cases for finding the complexity:
​ Worst case: the maximum number of comparison are made or maximum value of
f(n).
​ Average case: the average number of comparison are made or average value of f(n)
is determined. 1 0 -2 -3 5 6 -3 -2 0 1 5 6
​ Best Case: minimum number of comparison are made or minimum value of f(n).

Bubble Sort: In Bubble sort, Each element of the array is compared with its adjacent
element. The algorithm processes the list in passes. A list with n elements requires n-1
passes for sorting. Consider an array A of n elements whose elements are to be sorted by
using Bubble sort. The algorithm processes like following.
age | 2

1.​ In Pass 1, A[0] is compared with A[1], A[1] is compared with A[2], A[2] is compared
with A[3] and so on. At the end of pass 1, the largest element of the list is placed at
the highest index of the list.
2.​ In Pass 2, A[0] is compared with A[1], A[1] is compared with A[2] and so on. At the
end of Pass 2 the second largest element of the list is placed at the second highest
index of the list.
3.​ In pass n-1, A[0] is compared with A[1], A[1] is compared with A[2] and so on. At the
end of this pass. The smallest element of the list is placed at the first index of the list.
Algorithm:
​ Step 1: Repeat Step 2 For i = 0 to N-1
​ Step 2: Repeat For J = i + 1 to N - I
​ Step 3: IF A[J] > A[i]​
SWAP A[J] and A[i]​
[END OF INNER LOOP]​
[END OF OUTER LOOP
​ Step 4: EXIT
Example:
#include<stdio.h>
void main ()
{
int i, j,temp; 0 1 2 3 4 5 6 7 8 9
int a[10] = { 10, 9, 7, 101, 23, 44, 12, 78, 34, 23};
​ for(i = 0; i<10; i++) // 10
​ {
​ for(j = i+1; j<10; j++) // 9
​ {
​ if(a[j] > a[i]) 10>9
​ {
​ temp = a[i]; t=10
​ a[i] = a[j]; 9= a[j]
​ a[j] = temp; a[j]=10
​ }
​ }
​ } 9 10 7 101 23 44 12 78 34 23
​ printf("Printing Sorted Element List ...\n");
​ for(i = 0; i<10; i++)
​ {
​ printf("%d\n",a[i]);
​ }
}

Output:
Printing Sorted Element List . . .
age | 3

7
9
10
12
23
34
44
78
101

Insertion Sort:
Insertion sort is the simple sorting algorithm which is commonly used in the daily lives while
ordering a deck of cards. In this algorithm, we insert each element onto its proper place in
the sorted array. This is less efficient than the other sort algorithms like quick sort, merge
sort, etc.

Technique:
​ Consider an array A whose elements are to be sorted. Initially, A[0] is the only
element on the sorted set. In pass 1, A[1] is placed at its proper index in the array.
​ In pass 2, A[2] is placed at its proper index in the array. Likewise, in pass n-1, A[n-1] is
placed at its proper index into the array.
​ To insert an element A[k] to its proper index, we must compare it with all other
elements i.e. A[k-1], A[k-2], and so on until we find an element A[j] such that,
A[j]<=A[k].
​ All the elements from A[k-1] to A[j] need to be shifted and A[k] will be moved to
A[j+1].

Algorithm:
​ Step 1: Repeat Steps 2 to 5 for K = 1 to N-1
​ Step 2: SET TEMP = ARR[K]
​ Step 3: SET J = K - 1
​ Step 4: Repeat while TEMP <=ARR[J]​
SET ARR[J + 1] = ARR[J]​
SET J = J - 1​
[END OF INNER LOOP]
​ Step 5: SET ARR[J + 1] = TEMP​
[END OF LOOP]
​ Step 6: EXIT
age | 4

Example:
#include<stdio.h>
void main ()
{
int i,j, k,temp;
int a[10] = { 10, 9, 7, 101, 23, 44, 12, 78, 34, 23};
printf("\nprinting sorted elements...\n");
for(k=1; k<10; k++)
{
temp = a[k]; // temp=a[1]
j= k-1; //j=1-1=0
while(j>=0 && temp <= a[j]) //while(0>=0 && 1<=0)//while(0>=0 && a[1]=9 <= a[0]=10)
{
a[j+1] = a[j]; // a[0+1]=a[0]= 10=9
j = j-1; //
}
a[j+1] = temp; a[1]=10
}
for(i=0;i<10;i++) //traverse
{
printf("\n%d\n",a[i]); //values present in a[i]= 7 9 10 12 23 23 34 44 78 101
}
}

Output:
Printing Sorted Elements . . .
7
9
10
12
23
23
34
44
78
101

Selection Sort:
In selection sort, the smallest value among the unsorted elements of the array is selected in
every pass and inserted to its appropriate position into the array.
age | 5

First, find the smallest element of the array and place it on the first position. Then, find the
second smallest element of the array and place it on the second position. The process
continues until we get the sorted array.
The array with n elements is sorted by using n-1 pass of selection sort algorithm.

Technique:
​ In 1st pass, smallest element of the array is to be found along with its index pos.
then, swap A[0] and A[pos]. Thus A[0] is sorted, we now have n -1 elements
which are to be sorted.
​ In 2nd pas, position pos of the smallest element present in the sub-array A[n-1] is
found. Then, swap, A[1] and A[pos]. Thus A[0] and A[1] are sorted, we now left
with n-2 unsorted elements.
​ In n-1th pass, position pos of the smaller element between A[n-1] and A[n-2] is to
be found. Then, swap, A[pos] and A[n-1].
Algorithm:
SELECTION SORT(ARR, N)
o​ Step 1: Repeat Steps 2 and 3 for K = 1 to N-1
o​ Step 2: CALL SMALLEST(ARR, K, N, POS)
o​ Step 3: SWAP A[K] with ARR[POS]​
[END OF LOOP]
o​ Step 4: EXIT
SMALLEST (ARR, K, N, POS)
o​ Step 1: [INITIALIZE] SET SMALL = ARR[K]
o​ Step 2: [INITIALIZE] SET POS = K
o​ Step 3: Repeat for J = K+1 to N -1​
IF SMALL > ARR[J]​
SET SMALL = ARR[J]​
SET POS = J​
[END OF IF]​
[END OF LOOP]
o​ Step 4: RETURN POS

Example:
Consider the following array with 6 elements. Sort the elements of the array by using
selection sort.

Pass Pos A[0] A[1] A[2] A[3] A[4] A[5]


age | 6

A
10 2 3 90 43 56
=
1 1 2 10 3 90 43 56

2 2 2 3 10 90 43 56

3 2 2 3 10 90 43 56

4 4 2 3 10 43 90 56

5 5 2 3 10 43 56 90
{10, 2, 3, 90, 43, 56}.
Sorted A = {2, 3, 10, 43, 56, 90}

#include<stdio.h>
int smallest(int[],int,int);
void main ()
{
int a[10] = {10, 9, 7, 101, 23, 44, 12, 78, 34, 23};
int i,j,k,pos,temp;
for(i=0;i<10;i++)
{
pos = smallest(a,10,i);
temp = a[i];
a[i]=a[pos];
a[pos] = temp;
}
printf("\nprinting sorted elements...\n");
for(i=0;i<10;i++)
{
printf("%d\n",a[i]);
}
}
int smallest(int a[], int n, int i)
{
int small,pos,j;
small = a[i];
pos = i;
for(j=i+1;j<10;j++)
{
if(a[j]<small) // (10<2)
{
small = a[j];
pos=j;
}
}
age | 7

return pos;
}

Output:
printing sorted elements...
7
9
10
12
23
23
34
44
78
101

Complexity of Selection Sort Algorithm:


The number of f(n) comparisons in this algorithm is independent of its original order.
There are n-1 comparisons during pass 1 and n-2 comparison during pass 2.

Complexity Best Case Average Case Worst Case

Time Ω(n) θ(n2) o(n2)

Space o(1)

Shell Sort:
Shell sort is the generalization of insertion sort, which overcomes the drawbacks of insertion
sort by comparing elements separated by a gap of several positions.
It is a sorting algorithm that is an extended version of insertion sort. Shell sort has improved
the average time complexity of insertion sort. As similar to insertion sort, it is a
comparison-based and in-place sorting algorithm. Shell sort is efficient for medium-sized
data sets.

Algorithm:
1.​ ShellSort(a, n) // 'a' is the given array, 'n' is the size of array
2.​ for (interval = n/2; interval > 0; interval /= 2)
3.​ for ( i = interval; i < n; i += 1)
4.​ temp = a[i];
5.​ for (j = i; j >= interval && a[j - interval] > temp; j -= interval)
6.​ a[j] = a[j - interval];
7.​ a[j] = temp;
8.​ End ShellSort

Working of Shell Sort


To understand the working of the shell sort algorithm, let's take an unsorted array. It will be
easier to understand the shell sort via an example.
age | 8

Let the elements of array are -

In the first loop, n is equal to 8 (size of the array), so the elements are lying at the interval of
4 (n/2 = 4). Elements will be compared and swapped if they are not in order.
Here, in the first loop, the element at the 0th position will be compared with the element at
4th position. If the 0th element is greater, it will be swapped with the element at 4th position.
Otherwise, it remains the same. This process will continue for the remaining elements.
At the interval of 4, the sublists are {33, 12}, {31, 17}, {40, 25}, {8, 42}.

33 31 40 8 12 17 25 42: list
List=n/2; 8/2=4;
33 31 40 8: list 1== 33
12 17 25 42: list 2== 12
List[1] > list2[1]:
if(list[1]> list2[1])// (33>12) tru (31>17)true(40>25)true(8>42)false
{
Temp= list1[1];//swapping logic
List1[1]=list[2];
List[2]=temp;
}
33 31 40 8: list 1
12 17 25 42: list 2
12 17 25 8 33 31 40 42: updated list

Now, we have to compare the values in every sub-list. After comparing, we have to swap
them if required in the original array. After comparing and swapping, the updated array will
look as follows -
age | 9

In the second loop, elements are lying at the interval of 2 (n/4 = 2), where n = 8.
Now, we are taking the interval of 2 to sort the rest of the array. With an interval of 2, two
sublists will be generated - {12, 25, 33, 40}, and {17, 8, 31, 42}.

12 17 25 8 33 31 40 42
12>25wrong
17>8 true swapping logix will be implemented
25>33wrong
31>42 wrong
33>40wrong

12 8 25 17 33 31 40 42
Now, we again have to compare the values in every sub-list. After comparing, we have to
swap them if required in the original array. After comparing and swapping, the updated
array will look as follows -

In the third loop, elements are lying at the interval of 1 (n/8 = 1), where n = 8. At last, we use
the interval of value 1 to sort the rest of the array elements. In this step, shell sort uses
insertion sort to sort the array elements.
age | 10

Now, the array is sorted in ascending order.


Shell Sort Complexity:

Time Complexity

Case Time Complexity

Best Case O(n*logn)

Average Case O(n*log(n)2)

Worst Case O(n2)

o​ Best Case Complexity - It occurs when there is no sorting required, i.e., the array is
already sorted. The best-case time complexity of Shell sort is O(n*logn).
o​ Average Case Complexity - It occurs when the array elements are in jumbled order
that is not properly ascending and not properly descending. The average case time
complexity of Shell sort is O(n*logn).
o​ Worst Case Complexity - It occurs when the array elements are required to be sorted
in reverse order. That means suppose you have to sort the array elements in
ascending order, but its elements are in descending order. The worst-case time
complexity of Shell sort is O(n2).
age | 11

Space Complexity

Space Complexity O(1)

Stable NO

C program Example:

#include <stdio.h>
void print(int a[], int s) {
int i;
for (i = 0; i < s; ++i) {
printf( "%d ", a[i]);
}
}
void shell_Sort(int a[], int s) {
int gap, i;
for (gap = s / 2; gap > 0; gap /= 2) (gap=s/2;gap>0;gap=gap/2)
{
for ( i = gap; i < s; i += 1) //for(i=2;2<8;i=2+1)//fro(i=1;2<8;i=3
{
int temp = a[i];
int j;
for (j = i; j >= gap && a[j - gap] > temp; j -= gap) {
a[j] = a[gap-j];//a[1]=a[4-1]==a[1]=a[3]
}
a[j] = temp;
}
}
}
int main() {
int n,array[] = { 8, 2, 5, 9, 3, 1, 0 };
int size = n/2;
shell_Sort(array, size);//fun calling
printf("The sorted array is : \n");
print(array, size);
}

Divide and Conquer Technique:


In divide and conquer approach, the problem in hand, is divided into smaller sub-problems
and then each problem is solved independently. When we keep on dividing the subproblems
into even smaller sub-problems, we may eventually reach a stage where no more division is
possible. Those "atomic" smallest possible sub-problem (fractions) are solved. The solution
of all sub-problems is finally merged in order to obtain the solution of an original problem.

Divide And Conquer technique can be divided into the following three parts:
age | 12

Divide: This involves dividing the problem into smaller sub-problems.


Conquer: Solve sub-problems by calling recursively until solved.
Combine: Combine the sub-problems to get the final solution of the whole problem.

Merge Sort for Contiguous List (Arrays):


Merge Sort is a Divide and Conquer algorithm. It divides input array in two halves, calls itself
for the two halves and then merges the two sorted halves. The merge() function is used for
merging two halves. The merge(arr, l, m, r) is key process that assumes that arr[l..m] and
arr[m+1..r] are sorted and merges the two sorted sub-arrays into one.
Algorithm:
Merge sort keeps on dividing the list into equal halves until it can no more be divided. By
definition, if it is only one element in the list, it is sorted. Then, merge sort combines the
smaller sorted lists keeping the new list sorted too.

Step 1 − if it is only one element in the list it is already sorted, return.


Step 2 − divide the list recursively into two halves until it can no more be divided.
Step 3 − merge the smaller lists into new list in sorted order.

MergeSort(arr[], l, r)
If r > l
1. Find the middle point to divide the array into two halves:
middle m = l+ (r-l)/2
2. Call mergeSort for first half:
Call mergeSort(arr, l, m)
3. Call mergeSort for second half:
Call mergeSort(arr, m+1, r)
4. Merge the two halves sorted in step 2 and 3:
Call merge(arr, l, m, r)
age | 13

In the above image, we’ve shown the actual subarray in black and the resultant sorted
subarray in blue. Let us understand the detailed steps involved in performing a merge sort in
the above array:

●​ [6, 4, 5, 1, 2, 7, 3] is divided into [6, 4, 5, 1] and [2, 7, 3]


●​ [6, 4, 5, 1] is divided into [6, 4] and [5, 1]
●​ [6, 4] is divided into [6] and [4]
o​ [6] is a single element array and so, is sorted.
o​ [4] is a single element array and so, is sorted.
●​ [6] and [4] are merged into [4, 6]
●​ [5, 1] is divided into [5] and [1]
o​ [5] is a single element array and so, is sorted.
o​ [1] is a single element array and so, is sorted.
●​ [5] and [1] are merged into [1, 5]
o​ [4, 6] and [1, 5] are merged into [1, 4, 5, 6]

●​ [2, 7, 3] is divided into [2, 7] and [3]


●​ [2, 7] is divided into [2] and [7]
o​ [2] is a single element array and so, is sorted.
o​ [7] is a single element array and so, is sorted.
●​ [2] and [7] are merged into [2, 7]
●​ [3] is a single element array and so, is sorted.
●​ [2, 7] and [3] are merged into [2, 3, 7]
●​ [1, 4, 5, 6] and [2, 3, 7] are merged into [1, 2, 3, 4, 5, 6, 7]
age | 14

Observe one important point - we need a separate array in order to store the data of the
final merged array. This means that merge sort requires additional space.
o, that’s how merge sort works. Here is an animation that explains the same.

Merge Sort for Linked List:


Merge sort is often preferred for sorting a linked list. The slow random-access performance
of a linked list makes some other algorithms (such as quicksort) perform poorly, and others
(such as) completely impossible.
Let us understand the divide and conquer technique on linked list with the above example:
Divide Phase: heapsort
In this phase, the linked list is divided until size of list is 1.

Conquer Phase:
In this phase, divide linked list is sorted by comparing them by one and sorted list is passed
further.
age | 15

Algorithm:
MergeSort(headRef)
1) If head is NULL or there is only one element in the Linked List
then return.
2) Else divide the linked list into two halves.
FrontBackSplit(head, &a, &b); /* a and b are two halves */
3) Sort the two halves a and b.
MergeSort(a);
MergeSort(b);
4) Merge the sorted a and b (using SortedMerge() discussed here)
and update the head pointer using headRef.
*headRef = SortedMerge(a, b);

Peform merge sort fr arrays the following


a={10, 5, 1, 2 8,9 }
b={1 5 7 11 5 6}
age | 16

10 5 1 2 8 9​ ​ 1 5 7 11 5 6
10/5 1/2 8/ 9​ ​ 1/5 7/11 5/6
10 5 1 2 8 9​ ​ 1 5 7 11 5 6
5/10 1/2 8/9 ​ ​ 1/5 7/11 /5/6
1 2 5 8 9 10 ​ ​ 1 5 5 6 7 11
Combine both:
1 1 2 5 5 5 6 7 8 9 10 11

C program example to merge sort using linked list:

#include <stdio.h>
#include <stdlib.h>

struct node {
int number;
struct node *next;
};

/* add a node to the linked list */


struct node *addnode(int number, struct node *next);
/* preform merge sort on the linked list */
struct node *mergesort(struct node *head);
/* merge the lists.. */
struct node *merge(struct node *head_one, struct node *head_two);

int main(void)
{
struct node *head;
struct node *current;
struct node *next;
int n,i;

printf("Enter No. of elements u want to sort : ");


scanf("%d",&n);

int test[n];

printf("Enter elements : \n");


for(i=0;i<n;i++)
{
printf("Enter %d element : ",i+1);
scanf("%d",&test[i]);//test[10]
}

head = NULL;
/* insert some numbers into the linked list */
for(i = 0; i < n; i++)//i=0
age | 17

head = addnode(test[i], head);//addnode(test[0],head)//10, 105

/* sort the list */


head = mergesort(head);mergesort(head)=10, 105

/* print the list */


printf(" before after\n"), i = 0;
for(current = head; current != NULL; current = current->next)
printf("%4d\t%4d\n", test[i++], current->number);

/* free the list */


for(current = head; current != NULL; current = next)
next = current->next, free(current);

/* done... */
return 0;
}

/* add a node to the linked list */


struct node *addnode(int number, struct node *next) {
struct node *tnode;

tnode = (struct node*)malloc(sizeof(*tnode));

if(tnode != NULL) {
tnode->number = number;
tnode->next = next;
}

return tnode;
}

/* preform merge sort on the linked list */


struct node *mergesort(struct node *head) {
struct node *head_one;
struct node *head_two;

if((head == NULL) || (head->next == NULL))


return head;

head_one = head;
head_two = head->next;
while((head_two != NULL) && (head_two->next != NULL)) {
head = head->next;
head_two = head->next->next;
}
head_two = head->next;
age | 18

head->next = NULL;

return merge(mergesort(head_one), mergesort(head_two));


}

/* merge the lists.. */


struct node *merge(struct node *head_one, struct node *head_two) {
struct node *head_three;

if(head_one == NULL)
return head_two;

if(head_two == NULL)
return head_one;

if(head_one->number < head_two->number) {


head_three = head_one;
head_three->next = merge(head_one->next, head_two);
} else {
head_three = head_two;
head_three->next = merge(head_one, head_two->next);
}

return head_three;
}

Output:

Enter No. of elements u want to sort: 7

Enter elements:

Enter 1 element: 5
Enter 2 element: 2
Enter 3 element: 1
Enter 4 element: 4
Enter 5 element: 7
Enter 6 element: 9
Enter 7 element: 0

Before: 5 2 1 4 7 9 0
After: 0 1 2 4 5 7 9

Quick Sort for contiguous List (Arrays):


Quick sort is a highly efficient sorting algorithm and is based on partitioning of array of data
into smaller arrays. A large array is partitioned into two arrays one of which holds values
age | 19

smaller than the specified value, say pivot, based on which the partition is made and
another array holds values greater than the pivot value.

Quicksort partitions an array and then calls itself recursively twice to sort the two resulting
subarrays. This algorithm is quite efficient for large-sized data sets as its average and
worst-case complexity are O(n2), respectively.
Partition in Quick Sort:
Following animated representation explains how to find the pivot value in an array.

Quick Sort Algorithm:


Based on our understanding of partitioning in quick sort, we will now try to write an
algorithm for it, which is as follows.

Step 1 − Choose the highest index value has pivot


Step 2 − Take two variables to point left and right of the list excluding pivot
Step 3 − left points to the low index
Step 4 − right points to the high
Step 5 − while value at left is less than pivot move right
Step 6 − while value at right is greater than pivot move left
Step 7 − if both step 5 and step 6 does not match swap left and right
Step 8 − if left ≥ right, the point where they met is new pivot.

arr[] = {10, 80, 30, 90, 40, 50, 70}


Indexes: 0 1 2 3 4 5 6

low = 0, high = 6, pivot = arr[h] = 70


Initialize index of smaller element, i = -1

Traverse elements from j = low to high-1


j = 0 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j])
i=0
arr[] = {10, 80, 30, 90, 40, 50, 70} // No change as i and j
// are same

j = 1 : Since arr[j] > pivot, do nothing


age | 20

// No change in i and arr[]

j = 2 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j])


i=1
arr[] = {10, 30, 80, 90, 40, 50, 70} // We swap 80 and 30

j = 3 : Since arr[j] > pivot, do nothing


// No change in i and arr[]

j = 4 : Since arr[j] <= pivot, do i++ and swap(arr[i], arr[j])


i=2
arr[] = {10, 30, 40, 90, 80, 50, 70} // 80 and 40 Swapped
j = 5 : Since arr[j] <= pivot, do i++ and swap arr[i] with arr[j]
i=3
arr[] = {10, 30, 40, 50, 80, 90, 70} // 90 and 50 Swapped

We come out of loop because j is now equal to high-1.


Finally we place pivot at correct position by swapping
arr[i+1] and arr[high] (or pivot)
arr[] = {10, 30, 40, 50, 70, 90, 80} // 80 and 70 Swapped

Now 70 is at its correct place. All elements smaller than


70 are before it and all elements greater than 70 are after
it.

C program example to sort elements using quick sort:

#include <stdio.h>
// function to swap elements
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
// function to find the partition position
int partition(int array[], int low, int high) {
// select the rightmost element as pivot
int pivot = array[high];
// pointer for greater element
int i = (low - 1);
// traverse each element of the array
// compare them with the pivot
for (int j = low; j < high; j++) {
if (array[j] <= pivot) {
// if element smaller than pivot is found
// swap it with the greater element pointed by i
i++;
age | 21

// swap element at i with element at j


swap(&array[i], &array[j]);
}}
// swap the pivot element with the greater element at i
swap(&array[i + 1], &array[high]);
// return the partition point
return (i + 1);
}

void quickSort(int array[], int low, int high) {


if (low < high) {

// find the pivot element such that


// elements smaller than pivot are on left of pivot
// elements greater than pivot are on right of pivot
int pi = partition(array, low, high);

// recursive call on the left of pivot


quickSort(array, low, pi - 1);

// recursive call on the right of pivot


quickSort(array, pi + 1, high);
}
}

// function to print array elements


void printArray(int array[], int size) {
for (int i = 0; i < size; ++i) {
printf("%d ", array[i]);
}
printf("\n");
}

// main function
int main() {
int data[] = {8, 7, 2, 1, 0, 9, 6};

int n = sizeof(data) / sizeof(data[0]);

printf("Unsorted Array\n");
printArray(data, n);

// perform quicksort on data


quickSort(data, 0, n - 1);

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


printArray(data, n);
age | 22

Quicksort Complexity:
Time Complexity:
Best: O(n*log n)
Worst: O(n2)
Average: O(n*log n)
Space Complexity: O(log n)
Stability: No

1. Time Complexities
Worst Case Complexity [Big-O]: O(n2)
It occurs when the pivot element picked is either the greatest or the smallest element.

This condition leads to the case in which the pivot element lies in an extreme end of the
sorted array. One sub-array is always empty and another sub-array contains n - 1 elements.
Thus, quicksort is called only on this sub-array.
However, the quicksort algorithm has better performance for scattered pivots.

Best Case Complexity [Big-omega]: O(n*log n)


It occurs when the pivot element is always the middle element or near to the middle
element.

Average Case Complexity [Big-theta]: O(n*log n)


It occurs when the above conditions do not occur.

2. Space Complexity
The space complexity for quicksort is O(log n).

Searching is an operation or a technique that helps finds the place of a given element or
value in the list. Any search is said to be successful or unsuccessful depending upon whether
the element that is being searched is found or not.
Some of the standard searching technique that is being followed in the data structure is
listed below:
​ Linear Search or Sequential Search
a.​ Iterative Method
b.​ Recursive method
​ Binary Search
a.​ Iterative Method
b.​ Recursive method
Linear Search:
●​ Linear Search is the simplest searching algorithm.
●​ It traverses the array sequentially to locate the required element.
●​ It searches for an element by comparing it with each element of the array one by one.
●​ So, it is also called as Sequential Search.
age | 23

Linear Search Algorithm is applied when-


●​ No information is given about the array.
●​ The given array is unsorted or the elements are unordered.
●​ The list of data items is smaller.

As against this, searching in case of unsorted list also begins from the 0th element and
continues until the element or the end of the list is reached.

The list given below is the list of elements in an unsorted array. The array contains ten
elements. Suppose the element to be searched is '46', so 46 is compared with all the
elements starting from the 0th element, and the searching process ends where 46 is found,
or the list ends.
The performance of the linear search can be measured by counting the comparisons done to
find out an element. The number of comparison is 0(n).
Algorithm:
Linear Search ( Array A, Value x)

Step 1: Set i to 1
Step 2: if i > n then go to step 7
Step 3: if A[i] = x then go to step 6
Step 4: Set i to i + 1
Step 5: Go to Step 2
Step 6: Print Element x Found at index i and go to step 8
Step 7: Print element not found
Step 8: Exit

Example:
#include <stdio.h>
int main()​
{​
int array[100], search, c, n;
printf("Enter number of elements in array\n");​
scanf("%d", &n);
printf("Enter %d integer(s)\n", n);
for (c = 0; c < n; c++)​
scanf("%d", &array[c]);
printf("Enter a number to search\n");​
scanf("%d", &search);
for (c = 0; c < n; c++)​
{​
if (array[c] == search) /* If required element is found */​
{​
printf("%d is present at location %d.\n", search, c+1);​
age | 24

break;​
}​
}​
if (c == n)​
printf("%d isn't present in the array.\n", search);
return 0;​
}

Output:
Enter number of elements in array
5
Enter 5 integer(s)
2
5
6
9
4
Enter a number to search
4
4 is present at location 5.

Time Complexity Analysis-


Linear Search time complexity analysis is done below-
Best case-
In the best possible case,
●​ The element being searched may be found at the first position.
●​ In this case, the search terminates in success with just one comparison.
●​ Thus in best case, linear search algorithm takes O(1) operations.

Worst Case:
In the worst possible case,
●​ The element being searched may be present at the last position or not present in the
array at all.
●​ In the former case, the search terminates in success with n comparisons.
●​ In the later case, the search terminates in failure with n comparisons.
●​ Thus in worst case, linear search algorithm takes O(n) operations.
Binary Search:
Binary search is the search technique which works efficiently on the sorted lists. Hence, in
order to search an element into some list by using binary search technique, we must ensure
that the list is sorted.
Binary search follows divide and conquer approach in which, the list is divided into two
halves and the item is compared with the middle element of the list. If the match is found
then, the location of middle element is returned otherwise, we search into either of the
halves depending upon the result produced through the match.
age | 25

Algorithm:
BINARY_SEARCH (A, lower_bound, upper_bound, VAL)
o​ Step 1: [INITIALIZE] SET BEG = lower_bound​
END = upper_bound, POS = - 1
o​ Step 2: Repeat Steps 3 and 4 while BEG <=END
o​ Step 3: SET MID = (BEG + END)/2
o​ Step 4: IF A[MID] = VAL​
SET POS = MID​
PRINT POS​
Go to Step 6​
ELSE IF A[MID] > VAL​
SET END = MID - 1​
ELSE​
SET BEG = MID + 1​
[END OF IF]​
[END OF LOOP]
o​ Step 5: IF POS = -1​
PRINT "VALUE IS NOT PRESENT IN THE ARRAY"​
[END OF IF]
o​ Step 6: EXIT

Complexity:

SN Performance Complexity

1 Worst case O(log n)

2 Best case O(1)

3 Average Case O(log n)

4 Worst case space complexity O(1)

Example:
#include<stdio.h>
int binarySearch(int[], int, int, int);
void main ()
{
int arr[10] = {16, 19, 20, 23, 45, 56, 78, 90, 96, 100};
int item, location=-1;
printf("Enter the item which you want to search ");
scanf("%d",&item);
location = binarySearch(arr, 0, 9, item);
age | 26

if(location != -1)
{
printf("Item found at location %d",location);
}
else
{
printf("Item not found");
}
}
int binarySearch(int a[], int beg, int end, int item)
{
int mid;
if(end >= beg)
{
mid = (beg + end)/2;
if(a[mid] == item)
{
return mid+1;
}
else if(a[mid] < item)
{
return binarySearch(a,mid+1,end,item);
}
else
{
return binarySearch(a,beg,mid-1,item);
}
}
return -1;
}

Output:
Enter the item which you want to search
19
Item found at location 2

Binary Search Algorithm Advantages-


The advantages of binary search algorithm are-
●​ It eliminates half of the list from further searching by using the result of each comparison.
●​ It indicates whether the element being searched is before or after the current position in
the list.
●​ This information is used to narrow the search.
●​ For large lists of data, it works significantly better than linear search.
Binary Search Algorithm Disadvantages-
The disadvantages of binary search algorithm are-
age | 27

●​ It employs recursive approach which requires more stack space.


●​ Programming binary search algorithm is error prone and difficult.
●​ The interaction of binary search with memory hierarchy i.e. caching is poor.
(Because of its random access nature)

Difference between Linear & Binary Search:

BASIS FOR
LINEAR SEARCH BINARY SEARCH
COMPARISON

Time Complexity O(N) O(log 2 N)

Best case time First Element O(1) Centre Element O(1)

Prerequisite for an No required Array must be in sorted order


array

Worst case for N N comparisons are Can conclude after only log2N
number of elements required comparisons

Can be implemented Array and Linked list Cannot be directly implemented


on on linked list

Insert operation Easily inserted at the end Require processing to insert at its
of list proper place to maintain a sorted
list.

Algorithm type Iterative in nature Divide and conquer in nature

Usefulness Easy to use and no need Anyhow tricky algorithm and


for any ordered elements. elements should be organized in
order.

Lines of Code Less More

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy