Lab Assignment 4 (Searching and Sorting)
Lab Assignment 4 (Searching and Sorting)
Objective
This lab aims to implement various searching and sorting algorithms
and analyze their time complexity.
• Linear Search
• Binary Search
• Bubble sort
• Insertion Sort
• Selection Sort
• Quick Sort
• Merge Sort
Searching
• Searching is a methods to find the element in any data structure like array, linked-list, tree,
graph.
Searching
Sequential Binary
Search Search
Sequential Search Example
• Comparing the “target element” with middle most item of the array.
• Middle element=(low+high)/2
• If the middle element > “target element”, then search the target element from
the left side of the array. Otherwise, Search from the right side of the array.
In linear search input data need not to be in sorted. In binary search input data need to be in sorted order.
The time complexity of linear search O(n). The time complexity of binary search O(log n).
10 25 35 35 45 60
Unstable Sorting
25 10 35 45 60 35
10 25 35 35 45 60
Stable Sorting
2 1 1 4 5 3
1 1 2 3 4 5
Unstable Sorting
2 1 1 4 5 3
1 1 2 3 4 5
Analysis Criteria for Sorting Algorithm
Non-Adaptive sorting :- Does not take into account the elements which are already
sorted & force every single element to be re-ordered to confirm their sortedness.
Few important Sorting Algorithms
● Bubble Sort
● Selection Sort
● Insertion Sort
● Merge Sort
● Quick Sort
Bubble Sort
}
}
Bubble Sort Function
}
if (flag==false)
{ break;}
}
}
7 4 5 9 8 2 1 Unsorted
min swap
1 4 5 9 8 2 7
min swap
1 2 5 9 8 4 7
swap
min
1 2 4 9 8 5 7
min swap
1 2 4 5 8 9 7
min swap
1 2 4 5 7 9 8
1 2 4 5 7 8 9 Sorted
Selection Sort Algorithm (Function)
● Poor performance.
● Not suitable for most real-world scenarios.
● Unstable
Insertion Sort
3rd Pass 11 12 13 5 6 11 12 5 13 6
11 5 12 13 6
4th Pass 5 11 12 13 6 5 11 12 6 13
5 11 6 12 13
● Not suitable for most real-world scenarios: Due to its poor performance,
insertion sort is not suitable for use in most real-world scenarios where larger
datasets are involved. It is primarily used for educational purposes and small
datasets.
Merge Sort
Divide
Conquer
Merge Sort Algorithm
An integer in C is 4 bytes (32 bits), and the highest number it can
store is 2147483647. If we consider an array where the start index
is 2147483637 and the end index is 2147483647, then according
MergeSort(int arr[], int low, int high) { to the formula (low + high)/2, the sum (low+high) is 4294967284,
which exceeds the maximum value that can be stored in an integer
if (low < high) { variable. This results in integer overflow, making it impossible to
calculate the midpoint correctly.
mid = (low+high)/2; To solve this problem, it is a good practice to use the formula:
mid=low+(highlow)/2
Left part MergeSort(arr, low, mid); This approach prevents integer overflow.
For example, using this formula:
Right part MergeSort(arr, mid + 1, high); mid=2147483637+
(21474836472147483637)/2=2147483637+10/2=2147483637+5=2
147483642
Merge Merge(arr,low,mid,high); The correct midpoint is calculated without any overflow issues.
}}
Merge Function
void merge(int arr[], int low, int high, int mid)
{ i=0 j<=high
i<=mid j=mid+1
int i=low;
int j=mid+1;
int k=low; 3 27 38 43 9 10 82
int arrB[high+1];
while(i<=mid && j<=high) k=0
{
if (arr[i]<arr[j]){arrB[k]=arr[i]; i++; k++;} 3 9 10 27 38 43 82
else{arrB[k]=arr[j]; j++;k++;}
} arrB[high+1](Size of the array)
while(i<=mid){arrB[k]=arr[i]; i++; k++;}
while(j<=high){arrB[k]=arr[j]; j++; k++;}
for (i=low; i<=high; i++){arr[i]=arrB[i];}
}
Time complexity
● Best, Average and worst Case:- O(n logn)
T(n)=2T(n/2)+n; (1)
T(n/2)=2T(n/2^2)+n/2; (2)
Put T(n/2) value in equation 1.
=2(2T(n/4)+n/2) +n
= 2^2T(n/2^2)+ n+n
= 2^2T(n/2^2)+ 2*n
= 2^iT(n/2^i) + i*n ;
● It is a stable sort.
● Suitable for sorting large data sets.
● The divide and conquer strategy allows sorting elements in a parallel way,
which can be very beneficial in certain scenarios where the algorithm needs to
be efficient and running on multiple cores.
Merge Sort Disadvantages
● Not-In-Place
● It may not be efficient for small arrays, as the overhead of the divide-and-
conquer strategy can outweigh the benefits for small data sets.
● It's not always the best choice when working with real-time systems where
memory and time constraints are strict.
Quick Sort
● Quick sort uses divide and conquer to gain the same advantages as the merge
sort, while not using additional storage.
● It selects a "pivot" element from the array and partition the other elements
into two parts:
1. less than the pivot in the left side
2. greater than the pivot in right side.
● The pivot element is then in its correct position in the sorted array.
● The partitioning step is then repeated recursively on the two sub-arrays until
the entire array is sorted.
Quick Sort Example
Quick Sort Algorithm
● Always picks the middle element as the pivot. Time complexity on that
scenario is θ(nlogn).
● Sorted list (Worst Case): Select the first or last element is always picked as
a pivot. Time complexity on that case is O(𝑛2 ).
Best and Average case:- Time complexity
T(n)=2T(n/2)+n; (1)
T(n/2)=2T(n/2^2)+n/2; (2)
Put T(n/2) value in equation 1.
=2(2T(n/4)+n/2) +n
= 2^2T(n/2^2)+ n+n
= 2^2T(n/2^2)+ 2*n
= 2^iT(n/2^i) + i*n ;