KEMBAR78
Searching and Sorting Algorithms in Data Structures | PPTX
UNIT – II
Searching and Sorting
Searching
 Searching algorithms are methods or procedures used to find a specific item or element
within a collection of data.
 These algorithms are used for tasks like searching for a particular record in a database,
finding an element in a sorted list, or locating a file on a computer.
Types of searching algorithms:
1. Linear Search
2. Binary Search
3. Hashing
4. Interpolation Search
5. Tree-based Searching
6. Ternary Search
7. Jump Search
8. Exponential Search
9. Fibonacci Search
10. Interpolation Search for Trees
11. Hash-based Searching (e.g., Bloom Filter)
12. String Searching Algorithms
Method to use Linear Search
1. Start from the first element and compare each element with the search element.
2. If the element is found, return at which position element was found.
3. If the element is not found, return -1.
Linear Search or Sequential Search Algorithm:
 Linear Search is defined as a sequential search algorithm that starts at one end and goes
through each element of a list until the desired element is found, otherwise the search
continues till the end of the data set.
In Linear Search Algorithm,
 Every element is considered as a potential match for the key and checked for the same.
 If any element is found equal to the key, the search is successful and the index of that
element is returned.
 If no element is found equal to the key, the search says no match found.
For example: Consider the array arr[] = {10, 50, 30, 70, 80, 20, 90, 40} and key = 30
Step 1: Start from the first element (index 0) and compare key with each element (arr[i]).
 Comparing key with first element arr[0]. Since not equal, the iterator moves to the next
element as a potential match.
Compare key with arr[0]
 Comparing key with next element arr[1]. Since not equal, the iterator moves to the next
element as a potential match.
Step 2: When comparing arr[2] with key, the value matches. So, the Linear Search Algorithm
found the match and return the index of the element when key is found (here 2).
Algorithm for Linear Search
Steps for Linear search are as follows:
Linear_Search ( Array A [ n ], search_element x)
1: Set i to 1
2: if i > n then go to step 7
3: if A[i] = x then go to step 6
4: assign i+1 to i
5: Go to Step 2
6: Print Element x Found at index i and exit
7: display “element not found”
Example Program
#include <stdio.h>
int search(int arr[], int N, int x)
{
for (int i = 0; i < N; i++)
if (arr[i] == x)
return i;
return -1;
}
int search(int arr[], int N, int x)
{
for (int i = 0; i < N; i++)
if (arr[i] == x)
return i;
return -1;
}
int search(int arr[], int N, int x)
{
for (int i = 0; i < N; i++)
{
for (int i = 0; i < N; i++)
if (arr[i] == x)
return i;
return -1;
}
int main(void)
{
int arr[] = { 2, 3, 4, 10, 40};
int x = 10;
int N = sizeof(arr) / sizeof(arr[0]);
int N = sizeof(arr) /sizeof(arr[0]);
// Function call
int result = search(arr, N, x);
(result == -1)
printf("Element is not present in array")
printf("Element is present at index %d", result);
return 0;
}
Time Complexity:
 Best Case: The key might be present at the first index. So the best case complexity is O(1)
 Worst Case: The key might be present at the last index So the worst-case complexity is O(N)
where N is the size of the list.
 Average Case: O(N)
Auxiliary Space: O(1) as except for the variable to iterate through the list, no other variable is
used.
Advantages of Linear Search:
 Linear search can be used irrespective of whether the array is sorted or not. It can be used on
arrays of any data type.
 Does not require any additional memory.
 It is a well-suited algorithm for small datasets.
Drawbacks of Linear Search:
 Linear search has a time complexity of O(N), which in turn makes it slow for large datasets.
 Not suitable for large arrays.
When to use Linear Search?
 When we are dealing with a small dataset.
 When you are searching for a dataset stored in contiguous memory.
Binary Search Algorithm
 Binary search follows the 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 the middle element is returned.
There are two methods to implement the binary search algorithm -
 Iterative method
 Recursive method
The recursive methods of binary search follows the divide and conquer approach.
Let the elements of array are -
Let the element to search is, K = 56
To calculate the mid of the array -
mid = (beg + end)/2 // beg -> beginning element, end -> last element
So, in the given array -
beg = 0
end = 8
mid = (0 + 8)/2 = 4. So, 4 is the mid of the array.
Now, the element to search is found. So algorithm will return the index of the element matched.
Time Complexity
 Case Time Complexity
1. Best Case O(1)
2. Average Case O(logn)
3. Worst Case O(logn)
 Space Complexity
1. Space Complexity O(1)
Advantages of Binary Search algorithm:
 Easy to implement
 Makes search space half
 Enhanced time complexity
Disadvantage of Binary Search algorithm:
 Use only, if the data is sorted into a order.
Binary Search: Recursive Code
#include <stdio.h>
int binarySearch(int array[], int x, int low, int high) {
if (high >= low) {
int mid = low + (high - low) / 2;
// If found at mid, then return it
if (array[mid] == x)
return mid;
// Search the left half
if (array[mid] > x)
return binarySearch(array, x, low, mid - 1);
// Search the right half
return binarySearch(array, x, mid + 1, high);
}
return -1;
}
int main(void) {
int array[] = {3, 4, 5, 6, 7, 8, 9};
int n = sizeof(array) / sizeof(array[0]);
int x = 4;
int result = binarySearch(array, x, 0, n - 1);
if (result == -1)
printf("Not found");
else
printf("Element is found at index %d", result);
}
Output: Element is found at index 1
Binary Search: Iterative Method
#include <stdio.h>
int binarySearch(int array[], int x, int low, int high) {
// Repeat until the pointers low and high meet each other
while (low <= high) {
int mid = low + (high - low) / 2;
if (array[mid] == x)
return mid;
if (array[mid] < x)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
int main(void) {
int array[] = {3, 4, 5, 6, 7, 8, 9};
int n = sizeof(array) / sizeof(array[0]);
int x = 4;
int result = binarySearch(array, x, 0, n - 1);
if (result == -1)
printf("Not found");
else
printf("Element is found at index %d", result);
return 0;
}
Output: Element is found at index 1
Important Differences
Linear Search Binary Search
In linear search input data need not to be in
sorted.
In binary search input data need to be in sorted
order.
It is also called sequential search. It is also called half-interval search.
The time complexity of linear search O(n). The time complexity of binary search O(log n).
Multidimensional array can be used. Only single dimensional array is used.
Linear search performs equality comparisons Binary search performs ordering comparisons
It is less complex. It is more complex.
It is very slow process. It is very fast process
Sorting
Sorting:
• A Sorting Algorithm is used to rearrange a given array or list of elements according to
a comparison operator on the elements.
Example: The below list of characters is sorted in increasing order of their ASCII values.
Unsorted 170 45 90 802 24 2 66
Sorted 2 24 45 66 75 90 170 802
es of Sorting Algorithms:
Typ
There are many different types of sorting algorithms in data structures:
• Selection Sort
• Bubble Sort
• Merge Sort
• Quick Sort
Bubble Sort:
• Bubble Sort works by repeatedly swapping the adjacent elements if they are in the wrong
order.
• This algorithm is not suitable for large data sets.
• Average and worst-case time complexity is quite high.
• It traverses from left and compare adjacent elements and the higher one is placed at right
side.
• In this way, the largest element is moved to the rightmost end at first.
• This process is then continued to find the second largest.
Input: arr[] = {6, 3, 0, 5}
First Pass:
• The largest element is placed in its correct position, i.e., the end of the array.
Second Pass:
• Place the second largest element at correct position
Third Pass:
• Place the remaining two elements at their correct positions.
• Total no. of passes: n-1
• Total no. of comparisons: n*(n-1)/2
Advantage of Bubble Sort:
 It can detect whether the input is already sort.
Disadvantage of Bubble Sort:
 It is highly inefficient for large data sets.
Applications of Bubble Sort:
 How the contact list on your phone is sorted in alphabetical order.
Program - Bubble sort
#include <stdbool.h>
#include <stdio.h>
void swap(int* xp, int* yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// An optimized version of Bubble Sort
void bubbleSort(int arr[], int n)
{
int i, j;
bool swapped;
for (i = 0; i < n - 1; i++) {
swapped = false;
for (j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(&arr[j], &arr[j + 1]);
swapped = true;
}
}
if (swapped == false) // If no two elements were swapped by inner loop, then break
break;
}
}
void printArray(int arr[], int size) // Function to print an array
{
int i;
for (i = 0; i < size; i++)
printf("%d ", arr[i]);
}
int main() // main program to test above functions
{
int arr[] = { 64, 34, 25, 12, 22, 11, 90 };
int n = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, n);
printf("Sorted array: n");
printArray(arr, n);
return 0;
}
Selection Sort
• Selection sort works by repeatedly selecting the smallest (or largest) element from the
unsorted portion of the list.
• And moving it to the sorted portion of the list.
• The algorithm repeatedly selects the smallest (or largest) element from the unsorted
portion of the list and swaps it with the first element of the unsorted part.
• This process is repeated for the remaining unsorted portion until the entire list is sorted.
Lets consider the following array as an example:
arr[] = {64, 25, 12, 22, 11}
First pass:
• First, the whole array is traversed from index 0 to 4 sequentially.
• The first position where 64 is stored presently, after traversing whole array it is clear that
11 is the lowest value.
• Thus, replace 64 with 11.
Second Pass:
• Second position, where 25 is present, again traverse the rest of the array in a sequential
manner.
• After traversing, found that 12 is the second lowest value in the array, thus swap these
values.
Third Pass:
• Now, for third place, where 25 is present again traverses the rest of the array and find the
third least value present in the array.
• While traversing, 22 came out to be the third least value, thus swap 22 with element
present at third position.
Fourth pass:
• Similarly, for fourth position traverse the rest of the array and find the fourth least
element in the array.
• As 25 is the 4th lowest value hence, it will place at the fourth position.
Advantage of Selection Sort:
 It is stable
 Don’t require extra space
 More efficient
Disadvantage of Selection Sort:
 Does not work well on large datasets.
 It requires n-squared number of steps for sorting n elements.
Applications of Selection Sort:
 Sorting a list of students by their grades or names in a small class.
 Organizing files in a directory by date or size
// C program for implementation of selection sort
#include <stdio.h>
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void selectionSort(int arr[], int n)
{
int i, j, min_idx;
// One by one move boundary of unsorted subarray
for (i = 0; i < n-1; i++)
{
// Find the minimum element in unsorted array
min_idx = i;
for (j = i+1; j < n; j++)
if (arr[j] < arr[min_idx])
min_idx = j;
// Swap the found minimum element with the first element
if(min_idx != i)
swap(&arr[min_idx], &arr[i]);
}
}
/* Function to print an array */
void printArray(int arr[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf("n");
}
// Main program to test above functions
int main()
{
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr)/sizeof(arr[0]);
selectionSort(arr, n);
printf("Sorted array: n");
printArray(arr, n);
return 0; }
Merge Sort
• The process of merge sort is to divide the array into two halves, sort each half, and then
merge the sorted halves back together.
• This process is repeated until the entire array is sorted.
• Merge sort is a recursive algorithm that continuously splits the array in half until it cannot
be further divided i.e., the array has only one element left
• Lets consider an array arr[] = {38, 27, 43, 10}
• Initially divide the array into two equal halves:
Merge Sort
Advantage of Merge Sort:
 It is quicker for large data sets
 It has consistent running time.
Disadvantage of Merge Sort:
 Slower for smaller tasks.
 More memory spaces needed to store sub elements.
Applications of Merge Sort:
 Sorting a deck of playing cards
Example Program
#include <stdio.h>
void merge(int arr[], int left, int middle, int right)
{
int i, j, k;
int n1 = middle - left + 1;
int n2 = right - middle;
int L[n1], R[n2]; // Create temporary arrays
// Copy data to temporary arrays L[] and R[]
for (i = 0; i < n1; i++)
L[i] = arr[left + i];
for (j = 0; j < n2; j++)
R[j] = arr[middle + 1 + j];
// Merge the temporary arrays back into arr[left..right]
i = 0;
j = 0;
k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1) { // Copy the remaining elements of L[], if there are any
arr[k] = L[i];
i++;
k++;
}
while (j < n2) { // Copy the remaining elements of R[], if there are any
arr[k] = R[j];
j++;
k++;
}
}
void mergeSort(int arr[], int left, int right) { // Main function for merge sort
if (left < right) {
int middle = left + (right - left) / 2; // Same as (left+right)/2,
mergeSort(arr, left, middle); // Sort first and second halves
mergeSort(arr, middle + 1, right);
merge(arr, left, middle, right); // Merge the sorted halves
}
}
// Main program to test the merge sort
int main() {
int arr[] = {12, 11, 13, 5, 6, 7};
int arr_size = sizeof(arr) / sizeof(arr[0]);
printf("Given array is n");
for (int i = 0; i < arr_size; i++)
printf("%d ", arr[i]);
printf("n");
mergeSort(arr, 0, arr_size - 1);
printf("Sorted array is n");
for (int i = 0; i < arr_size; i++)
printf("%d ", arr[i]);
printf("n");
return 0;
}
Quick Sort
• QuickSort is based on the Divide and Conquer algorithm
• It picks an element as a pivot and partitions the given array around the picked pivot by
placing the pivot in its correct position in the sorted array.
• The key process in quickSort is a partition().
• The target of partitions is to place the pivot (any element can be chosen to be a pivot) at
its correct position in the sorted array
• And put all smaller elements to the left of the pivot, and all greater elements to the right
of the pivot.
Choice of Pivot:
There are many different choices for picking pivots.
• Pick the first element as a pivot.
• Pick the last element as a pivot
• Pick a random element as a pivot
• Pick the middle as the pivot.
Consider: arr[] = {24, 9, 29, 14, 19,27}.
• We consider the leftmost element as pivot. So, a[left]=24, a[right]=27 and a[pivot]=24.
• Since, pivot is at left, so algorithm starts from right and move towards left.
• Now, a[pivot] < a[right], so algorithm moves forward one position towards left, i.e.
Here, 24 > 19, which means pivot is greater than right element, so algorithm swap a[pivot] with
a[right] and pivot moves to right.
Now, pivot is at right, so algorithm starts from left and moves right.
Now, a[left] = 9, a[right] = 24 and a[pivot] = 24. As pivot is greater than left, so algorithm moves
one position to right, as
Now, a[left]=29, a[right]=24 and a[pivot]=24. As a[pivot]<a[left], so, swap the pivot and left
element, i.e.,
Since, pivot is at left, so algorithm starts from right, and move to left. Now, a[left] = 24, a[right]
= 29 and a[pivot] = 24. As pivot is lesser than right, so algorithm moves one position to left, as
Now, a[left]=24, a[right]=14 and a[pivot]=24. As a[pivot]>a[right], so, swap the pivot and right
element, i.e.,
Now, a[left] = 14, a[right] = 24 and a[pivot] = 24. Pivot is right so algorithm starts from left and
moves to right
Now, a[left]=24, a[right]=24 and a[pivot]=24. So, pivot, left and right are pointing the same
element. It represents the termination of procedure.
Advantage of Quick Sort:
 Fast
 Easy to implement
 Does not extra space
Disadvantage of Quick Sort:
 Unstable
 Sensitive to the choice of pivot
 It cause stack overflow if the recursion depth is too high.
Application of Quick Sort:
 Data visualization.
C Program
#include <stdio.h>
// Function to partition the array and return the pivot index
int partition(int arr[], int low, int high)
{
int pivot = arr[high]; // Choose the rightmost element as the pivot
int i = (low - 1); // Index of smaller element
for (int j = low; j <= high - 1; j++)
{
// If the current element is smaller than or equal to the pivot
if (arr[j] <= pivot)
{
i++;
// Swap arr[i] and arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// Swap arr[i + 1] and arr[high] (pivot)
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return (i + 1); // Return the pivot index
}
// Function to implement Quick Sort
void quickSort(int arr[], int low, int high) {
if (low < high) {
// Find the pivot index such that elements on the left are smaller,
// and elements on the right are greater
int pivotIndex = partition(arr, low, high);
// Recursively sort the subarrays
quickSort(arr, low, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, high);
}
}
// Main program to test the quick sort
int main() {
int arr[] = {12, 11, 13, 5, 6, 7};
int arr_size = sizeof(arr) / sizeof(arr[0]);
printf("Given array is n");
for (int i = 0; i < arr_size; i++)
printf("%d ", arr[i]);
printf("n");
quickSort(arr, 0, arr_size - 1);
printf("Sorted array is n");
for (int i = 0; i < arr_size; i++)
printf("%d ", arr[i]);
printf("n");
return 0;
}

Searching and Sorting Algorithms in Data Structures

  • 1.
    UNIT – II Searchingand Sorting Searching  Searching algorithms are methods or procedures used to find a specific item or element within a collection of data.  These algorithms are used for tasks like searching for a particular record in a database, finding an element in a sorted list, or locating a file on a computer. Types of searching algorithms: 1. Linear Search 2. Binary Search 3. Hashing 4. Interpolation Search 5. Tree-based Searching 6. Ternary Search 7. Jump Search 8. Exponential Search 9. Fibonacci Search 10. Interpolation Search for Trees 11. Hash-based Searching (e.g., Bloom Filter) 12. String Searching Algorithms
  • 2.
    Method to useLinear Search 1. Start from the first element and compare each element with the search element. 2. If the element is found, return at which position element was found. 3. If the element is not found, return -1. Linear Search or Sequential Search Algorithm:  Linear Search is defined as a sequential search algorithm that starts at one end and goes through each element of a list until the desired element is found, otherwise the search continues till the end of the data set. In Linear Search Algorithm,  Every element is considered as a potential match for the key and checked for the same.  If any element is found equal to the key, the search is successful and the index of that element is returned.  If no element is found equal to the key, the search says no match found. For example: Consider the array arr[] = {10, 50, 30, 70, 80, 20, 90, 40} and key = 30 Step 1: Start from the first element (index 0) and compare key with each element (arr[i]).  Comparing key with first element arr[0]. Since not equal, the iterator moves to the next element as a potential match.
  • 3.
    Compare key witharr[0]  Comparing key with next element arr[1]. Since not equal, the iterator moves to the next element as a potential match. Step 2: When comparing arr[2] with key, the value matches. So, the Linear Search Algorithm found the match and return the index of the element when key is found (here 2).
  • 4.
    Algorithm for LinearSearch Steps for Linear search are as follows: Linear_Search ( Array A [ n ], search_element x) 1: Set i to 1 2: if i > n then go to step 7 3: if A[i] = x then go to step 6 4: assign i+1 to i 5: Go to Step 2 6: Print Element x Found at index i and exit 7: display “element not found” Example Program #include <stdio.h> int search(int arr[], int N, int x) { for (int i = 0; i < N; i++) if (arr[i] == x) return i; return -1; } int search(int arr[], int N, int x) { for (int i = 0; i < N; i++) if (arr[i] == x) return i; return -1; } int search(int arr[], int N, int x) { for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) if (arr[i] == x) return i; return -1; }
  • 5.
    int main(void) { int arr[]= { 2, 3, 4, 10, 40}; int x = 10; int N = sizeof(arr) / sizeof(arr[0]); int N = sizeof(arr) /sizeof(arr[0]); // Function call int result = search(arr, N, x); (result == -1) printf("Element is not present in array") printf("Element is present at index %d", result); return 0; } Time Complexity:  Best Case: The key might be present at the first index. So the best case complexity is O(1)  Worst Case: The key might be present at the last index So the worst-case complexity is O(N) where N is the size of the list.  Average Case: O(N) Auxiliary Space: O(1) as except for the variable to iterate through the list, no other variable is used. Advantages of Linear Search:  Linear search can be used irrespective of whether the array is sorted or not. It can be used on arrays of any data type.  Does not require any additional memory.  It is a well-suited algorithm for small datasets. Drawbacks of Linear Search:  Linear search has a time complexity of O(N), which in turn makes it slow for large datasets.  Not suitable for large arrays. When to use Linear Search?  When we are dealing with a small dataset.  When you are searching for a dataset stored in contiguous memory.
  • 6.
    Binary Search Algorithm Binary search follows the 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 the middle element is returned. There are two methods to implement the binary search algorithm -  Iterative method  Recursive method The recursive methods of binary search follows the divide and conquer approach. Let the elements of array are - Let the element to search is, K = 56 To calculate the mid of the array - mid = (beg + end)/2 // beg -> beginning element, end -> last element So, in the given array - beg = 0 end = 8 mid = (0 + 8)/2 = 4. So, 4 is the mid of the array.
  • 7.
    Now, the elementto search is found. So algorithm will return the index of the element matched. Time Complexity  Case Time Complexity 1. Best Case O(1) 2. Average Case O(logn) 3. Worst Case O(logn)  Space Complexity 1. Space Complexity O(1)
  • 8.
    Advantages of BinarySearch algorithm:  Easy to implement  Makes search space half  Enhanced time complexity Disadvantage of Binary Search algorithm:  Use only, if the data is sorted into a order. Binary Search: Recursive Code #include <stdio.h> int binarySearch(int array[], int x, int low, int high) { if (high >= low) { int mid = low + (high - low) / 2; // If found at mid, then return it if (array[mid] == x) return mid; // Search the left half if (array[mid] > x) return binarySearch(array, x, low, mid - 1); // Search the right half return binarySearch(array, x, mid + 1, high); } return -1; } int main(void) { int array[] = {3, 4, 5, 6, 7, 8, 9}; int n = sizeof(array) / sizeof(array[0]); int x = 4; int result = binarySearch(array, x, 0, n - 1); if (result == -1) printf("Not found");
  • 9.
    else printf("Element is foundat index %d", result); } Output: Element is found at index 1 Binary Search: Iterative Method #include <stdio.h> int binarySearch(int array[], int x, int low, int high) { // Repeat until the pointers low and high meet each other while (low <= high) { int mid = low + (high - low) / 2; if (array[mid] == x) return mid; if (array[mid] < x) low = mid + 1; else high = mid - 1; } return -1; } int main(void) { int array[] = {3, 4, 5, 6, 7, 8, 9}; int n = sizeof(array) / sizeof(array[0]); int x = 4; int result = binarySearch(array, x, 0, n - 1); if (result == -1) printf("Not found"); else printf("Element is found at index %d", result);
  • 10.
    return 0; } Output: Elementis found at index 1 Important Differences Linear Search Binary Search In linear search input data need not to be in sorted. In binary search input data need to be in sorted order. It is also called sequential search. It is also called half-interval search. The time complexity of linear search O(n). The time complexity of binary search O(log n). Multidimensional array can be used. Only single dimensional array is used. Linear search performs equality comparisons Binary search performs ordering comparisons It is less complex. It is more complex. It is very slow process. It is very fast process
  • 11.
    Sorting Sorting: • A SortingAlgorithm is used to rearrange a given array or list of elements according to a comparison operator on the elements. Example: The below list of characters is sorted in increasing order of their ASCII values. Unsorted 170 45 90 802 24 2 66 Sorted 2 24 45 66 75 90 170 802 es of Sorting Algorithms: Typ There are many different types of sorting algorithms in data structures: • Selection Sort • Bubble Sort • Merge Sort • Quick Sort Bubble Sort: • Bubble Sort works by repeatedly swapping the adjacent elements if they are in the wrong order. • This algorithm is not suitable for large data sets. • Average and worst-case time complexity is quite high. • It traverses from left and compare adjacent elements and the higher one is placed at right side. • In this way, the largest element is moved to the rightmost end at first. • This process is then continued to find the second largest. Input: arr[] = {6, 3, 0, 5}
  • 12.
    First Pass: • Thelargest element is placed in its correct position, i.e., the end of the array. Second Pass: • Place the second largest element at correct position Third Pass: • Place the remaining two elements at their correct positions.
  • 13.
    • Total no.of passes: n-1 • Total no. of comparisons: n*(n-1)/2 Advantage of Bubble Sort:  It can detect whether the input is already sort. Disadvantage of Bubble Sort:  It is highly inefficient for large data sets. Applications of Bubble Sort:  How the contact list on your phone is sorted in alphabetical order. Program - Bubble sort #include <stdbool.h> #include <stdio.h> void swap(int* xp, int* yp) { int temp = *xp; *xp = *yp; *yp = temp; } // An optimized version of Bubble Sort void bubbleSort(int arr[], int n) { int i, j; bool swapped; for (i = 0; i < n - 1; i++) { swapped = false; for (j = 0; j < n - i - 1; j++) {
  • 14.
    if (arr[j] >arr[j + 1]) { swap(&arr[j], &arr[j + 1]); swapped = true; } } if (swapped == false) // If no two elements were swapped by inner loop, then break break; } } void printArray(int arr[], int size) // Function to print an array { int i; for (i = 0; i < size; i++) printf("%d ", arr[i]); } int main() // main program to test above functions { int arr[] = { 64, 34, 25, 12, 22, 11, 90 }; int n = sizeof(arr) / sizeof(arr[0]); bubbleSort(arr, n); printf("Sorted array: n"); printArray(arr, n); return 0; }
  • 15.
    Selection Sort • Selectionsort works by repeatedly selecting the smallest (or largest) element from the unsorted portion of the list. • And moving it to the sorted portion of the list. • The algorithm repeatedly selects the smallest (or largest) element from the unsorted portion of the list and swaps it with the first element of the unsorted part. • This process is repeated for the remaining unsorted portion until the entire list is sorted. Lets consider the following array as an example: arr[] = {64, 25, 12, 22, 11} First pass: • First, the whole array is traversed from index 0 to 4 sequentially. • The first position where 64 is stored presently, after traversing whole array it is clear that 11 is the lowest value. • Thus, replace 64 with 11. Second Pass: • Second position, where 25 is present, again traverse the rest of the array in a sequential manner. • After traversing, found that 12 is the second lowest value in the array, thus swap these values.
  • 16.
    Third Pass: • Now,for third place, where 25 is present again traverses the rest of the array and find the third least value present in the array. • While traversing, 22 came out to be the third least value, thus swap 22 with element present at third position. Fourth pass: • Similarly, for fourth position traverse the rest of the array and find the fourth least element in the array. • As 25 is the 4th lowest value hence, it will place at the fourth position.
  • 17.
    Advantage of SelectionSort:  It is stable  Don’t require extra space  More efficient Disadvantage of Selection Sort:  Does not work well on large datasets.  It requires n-squared number of steps for sorting n elements. Applications of Selection Sort:  Sorting a list of students by their grades or names in a small class.  Organizing files in a directory by date or size // C program for implementation of selection sort #include <stdio.h> void swap(int *xp, int *yp) { int temp = *xp; *xp = *yp; *yp = temp; } void selectionSort(int arr[], int n) { int i, j, min_idx; // One by one move boundary of unsorted subarray for (i = 0; i < n-1; i++) { // Find the minimum element in unsorted array min_idx = i;
  • 18.
    for (j =i+1; j < n; j++) if (arr[j] < arr[min_idx]) min_idx = j; // Swap the found minimum element with the first element if(min_idx != i) swap(&arr[min_idx], &arr[i]); } } /* Function to print an array */ void printArray(int arr[], int size) { int i; for (i=0; i < size; i++) printf("%d ", arr[i]); printf("n"); } // Main program to test above functions int main() { int arr[] = {64, 25, 12, 22, 11}; int n = sizeof(arr)/sizeof(arr[0]); selectionSort(arr, n); printf("Sorted array: n"); printArray(arr, n); return 0; }
  • 19.
    Merge Sort • Theprocess of merge sort is to divide the array into two halves, sort each half, and then merge the sorted halves back together. • This process is repeated until the entire array is sorted. • Merge sort is a recursive algorithm that continuously splits the array in half until it cannot be further divided i.e., the array has only one element left • Lets consider an array arr[] = {38, 27, 43, 10} • Initially divide the array into two equal halves: Merge Sort
  • 20.
    Advantage of MergeSort:  It is quicker for large data sets  It has consistent running time. Disadvantage of Merge Sort:  Slower for smaller tasks.  More memory spaces needed to store sub elements. Applications of Merge Sort:  Sorting a deck of playing cards Example Program #include <stdio.h> void merge(int arr[], int left, int middle, int right) { int i, j, k; int n1 = middle - left + 1; int n2 = right - middle; int L[n1], R[n2]; // Create temporary arrays // Copy data to temporary arrays L[] and R[] for (i = 0; i < n1; i++) L[i] = arr[left + i]; for (j = 0; j < n2; j++) R[j] = arr[middle + 1 + j]; // Merge the temporary arrays back into arr[left..right] i = 0; j = 0; k = left; while (i < n1 && j < n2) {
  • 21.
    if (L[i] <=R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } while (i < n1) { // Copy the remaining elements of L[], if there are any arr[k] = L[i]; i++; k++; } while (j < n2) { // Copy the remaining elements of R[], if there are any arr[k] = R[j]; j++; k++; } } void mergeSort(int arr[], int left, int right) { // Main function for merge sort if (left < right) { int middle = left + (right - left) / 2; // Same as (left+right)/2, mergeSort(arr, left, middle); // Sort first and second halves mergeSort(arr, middle + 1, right);
  • 22.
    merge(arr, left, middle,right); // Merge the sorted halves } } // Main program to test the merge sort int main() { int arr[] = {12, 11, 13, 5, 6, 7}; int arr_size = sizeof(arr) / sizeof(arr[0]); printf("Given array is n"); for (int i = 0; i < arr_size; i++) printf("%d ", arr[i]); printf("n"); mergeSort(arr, 0, arr_size - 1); printf("Sorted array is n"); for (int i = 0; i < arr_size; i++) printf("%d ", arr[i]); printf("n"); return 0; }
  • 23.
    Quick Sort • QuickSortis based on the Divide and Conquer algorithm • It picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. • The key process in quickSort is a partition(). • The target of partitions is to place the pivot (any element can be chosen to be a pivot) at its correct position in the sorted array • And put all smaller elements to the left of the pivot, and all greater elements to the right of the pivot. Choice of Pivot: There are many different choices for picking pivots. • Pick the first element as a pivot. • Pick the last element as a pivot • Pick a random element as a pivot • Pick the middle as the pivot. Consider: arr[] = {24, 9, 29, 14, 19,27}. • We consider the leftmost element as pivot. So, a[left]=24, a[right]=27 and a[pivot]=24. • Since, pivot is at left, so algorithm starts from right and move towards left. • Now, a[pivot] < a[right], so algorithm moves forward one position towards left, i.e.
  • 24.
    Here, 24 >19, which means pivot is greater than right element, so algorithm swap a[pivot] with a[right] and pivot moves to right. Now, pivot is at right, so algorithm starts from left and moves right. Now, a[left] = 9, a[right] = 24 and a[pivot] = 24. As pivot is greater than left, so algorithm moves one position to right, as Now, a[left]=29, a[right]=24 and a[pivot]=24. As a[pivot]<a[left], so, swap the pivot and left element, i.e.,
  • 25.
    Since, pivot isat left, so algorithm starts from right, and move to left. Now, a[left] = 24, a[right] = 29 and a[pivot] = 24. As pivot is lesser than right, so algorithm moves one position to left, as Now, a[left]=24, a[right]=14 and a[pivot]=24. As a[pivot]>a[right], so, swap the pivot and right element, i.e., Now, a[left] = 14, a[right] = 24 and a[pivot] = 24. Pivot is right so algorithm starts from left and moves to right Now, a[left]=24, a[right]=24 and a[pivot]=24. So, pivot, left and right are pointing the same element. It represents the termination of procedure. Advantage of Quick Sort:  Fast  Easy to implement  Does not extra space Disadvantage of Quick Sort:  Unstable  Sensitive to the choice of pivot  It cause stack overflow if the recursion depth is too high. Application of Quick Sort:
  • 26.
     Data visualization. CProgram #include <stdio.h> // Function to partition the array and return the pivot index int partition(int arr[], int low, int high) { int pivot = arr[high]; // Choose the rightmost element as the pivot int i = (low - 1); // Index of smaller element for (int j = low; j <= high - 1; j++) { // If the current element is smaller than or equal to the pivot if (arr[j] <= pivot) { i++; // Swap arr[i] and arr[j] int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } // Swap arr[i + 1] and arr[high] (pivot) int temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp;
  • 27.
    return (i +1); // Return the pivot index } // Function to implement Quick Sort void quickSort(int arr[], int low, int high) { if (low < high) { // Find the pivot index such that elements on the left are smaller, // and elements on the right are greater int pivotIndex = partition(arr, low, high); // Recursively sort the subarrays quickSort(arr, low, pivotIndex - 1); quickSort(arr, pivotIndex + 1, high); } } // Main program to test the quick sort int main() { int arr[] = {12, 11, 13, 5, 6, 7}; int arr_size = sizeof(arr) / sizeof(arr[0]); printf("Given array is n"); for (int i = 0; i < arr_size; i++) printf("%d ", arr[i]); printf("n"); quickSort(arr, 0, arr_size - 1); printf("Sorted array is n"); for (int i = 0; i < arr_size; i++) printf("%d ", arr[i]);
  • 28.