Followers

Friday, August 4, 2023

Bubble sort- The commonly used sorting algorithm.


In C programming, sorting refers to the process of arranging elements in a specific order. The most common sorting order is ascending or descending numerical order, but elements can also be sorted based on other criteria, such as alphabetical order, frequency, or any custom-defined comparison.

Sorting is a fundamental algorithmic operation and is widely used in various applications, such as searching, data analysis, and optimisation. There are several sorting algorithms available in C programming, each with its own strengths and weaknesses. The choice of sorting algorithm depends on the size of the data, the distribution of the data, and the specific requirements of the application.

Let's discuss the commonly used Bubble Sort algorithm in C programming:

  1. Bubble Sort:
    Bubble Sort is a simple sorting algorithm that repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. The pass through the list is repeated until the list is sorted.

Example implementation of Bubble Sort in C:

c
#include <stdio.h> void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } void bubbleSort(int arr[], int n) { int i, j; for (i = 0; i < n - 1; i++) { for (j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { swap(&arr[j], &arr[j + 1]); } } } } int main() { int arr[] = {64, 34, 25, 12, 22, 11, 90}; int n = sizeof(arr) / sizeof(arr[0]); printf("Original array: "); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } bubbleSort(arr, n); printf("\nSorted array: "); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; }

Sorting Algorithm - Which sorting algorithm is the fastest?


The fastest sorting algorithm can vary depending on the size and distribution of the data being sorted. Different sorting algorithms have different time complexities and perform better under specific circumstances. The following are some commonly used sorting algorithms and their average time complexities:

  1. Merge Sort: O(n log n)
  2. Quick Sort: O(n log n) on average (can be O(n^2) in worst case)
  3. Heap Sort: O(n log n)
  4. Intro Sort (a hybrid of Quick Sort, Heap Sort, and Insertion Sort): O(n log n)
  5. Tim Sort: O(n log n)
  6. Radix Sort (for integers): O(n * k) where k is the number of digits in the maximum number

For smaller datasets, simpler algorithms like Bubble Sort or Insertion Sort may perform well despite their higher time complexity (O(n^2)) because of their low overhead.

It's important to note that the time complexity mentioned above represents the number of comparisons and swaps the algorithm performs to sort the data. However, the actual running time can also be influenced by other factors like memory access patterns, cache locality, and implementation details.

In general, when dealing with a large amount of data, Quick Sort and Merge Sort are often considered fast and efficient choices. However, it's always a good idea to analyse the specific characteristics of your data and run benchmarks to determine the best sorting algorithm for your particular use case. Additionally, there are hybrid sorting algorithms that combine the strengths of multiple algorithms to achieve optimal performance in different scenarios.

Step-by-step explanation of how Merge Sort works

 

Merge Sort is a popular and efficient sorting algorithm based on the divide-and-conquer approach. It divides the input array into two halves, recursively sorts each half, and then merges the two sorted halves to produce the final sorted output.

Here's a step-by-step explanation of how Merge Sort works:

  1. 1. Divide: The input array is divided into two equal (or almost equal) halves. This step is performed recursively until each subarray contains only one element.

  2. 2. Conquer: The subarrays with a single element are trivially sorted, as a single element is always considered sorted.

  3. 3. Merge: The sorted subarrays are merged back together to form larger sorted subarrays. This process continues until the entire array is merged back into a single sorted array.

The merging process is the key component of Merge Sort. To merge two sorted arrays, you compare the elements from both arrays one by one and place them in the correct order in a new temporary array. The merged array is then copied back into the original array.

Here's a high-level overview of the merge step:

  1. 1. Create two pointers, one for each subarray.
  2. 2. Compare the elements pointed by both pointers.
  3. 3. Choose the smaller (or larger, depending on the desired sorting order) element and add it to the merged array.
  4. 4. Move the pointer of the array from which the element was selected to the next element.
  5. 5. Repeat steps 2-4 until all elements from both subarrays are added to the merged array.

Let's see a C implementation of Merge Sort:

c
#include <stdio.h> void merge(int arr[], int left, int mid, int right) { int i, j, k; int n1 = mid - left + 1; int n2 = right - mid; // Create temporary arrays to store the two subarrays int L[n1], R[n2]; // Copy data to temporary arrays for (i = 0; i < n1; i++) L[i] = arr[left + i]; for (j = 0; j < n2; j++) R[j] = arr[mid + 1 + j]; // Merge the two temporary arrays back into arr[] i = 0; // Initial index of the first subarray j = 0; // Initial index of the second subarray k = left; // Initial index of the merged subarray while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } // Copy the remaining elements of L[], if any while (i < n1) { arr[k] = L[i]; i++; k++; } // Copy the remaining elements of R[], if any while (j < n2) { arr[k] = R[j]; j++; k++; } } void mergeSort(int arr[], int left, int right) { if (left < right) { int mid = left + (right - left) / 2; // To avoid overflow for large left and right values // Sort the first and second halves mergeSort(arr, left, mid); mergeSort(arr, mid + 1, right); // Merge the sorted halves merge(arr, left, mid, right); } } int main() { int arr[] = {64, 34, 25, 12, 22, 11, 90}; int n = sizeof(arr) / sizeof(arr[0]); printf("Original array: "); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } mergeSort(arr, 0, n - 1); printf("\nSorted array: "); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; }

Merge Sort has a time complexity of O(n log n) in the average, best, and worst cases, making it very efficient for large datasets. Additionally, Merge Sort is a stable sorting algorithm, meaning that the relative order of equal elements is preserved during the sorting process.