Sorting (1)
Sorting (1)
Insertion Sort
• Insertion sort is a simple sorting algorithm that works by building a sorted array
one element at a time. It is considered an ” in-place ” sorting algorithm, meaning
it doesn’t require any additional memory space beyond the original array.
• To achieve insertion sort, follow these steps:
• We start with second element of the array as first element in the array is assumed
to be sorted.
• Compare second element with the first element and check if the second element
is smaller then swap them.
• Move to the third element and compare it with the second element, then the first
element and swap as necessary to put it in the correct position among the first
three elements.
• Continue this process, comparing each element with the ones before it and
swapping as needed to place it in the correct position among the sorted
elements.
• Repeat until the entire array is sorted.
Working of Insertion Sort Algorithm
• Time Complexity:
– Best Case: O(n log n), When the array is already
sorted or nearly sorted.
– Average Case: O(n log n), When the array is
randomly ordered.
– Worst Case: O(n log n), When the array is sorted in
reverse order.
• Auxiliary Space: O(n), Additional space is
required for the temporary array used during
merging.
Contd..
• Applications of Merge Sort:
• Sorting large datasets
• External sorting (when the dataset is too large to fit in memory)
• Inversion counting
• Merge Sort and its variations are used in library methods of programming languages. For example its variation TimSort is
used in Python, Java Android and Swift. The main reason why it is preferred to sort non-primitive types is stability which is
not there in QuickSort. For example Arrays.sort in Java uses QuickSort while Collections.sort uses MergeSort.
• It is a preferred algorithm for sorting Linked lists.
• It can be easily parallelized as we can independently sort subarrays and then merge.
• The merge function of merge sort to efficiently solve the problems like union and intersection of two sorted arrays.
• Advantages of Merge Sort:
• Stability : Merge sort is a stable sorting algorithm, which means it maintains the relative order of equal elements in the
input array.
• Guaranteed worst-case performance: Merge sort has a worst-case time complexity of O(N logN) , which means it performs
well even on large datasets.
• Simple to implement: The divide-and-conquer approach is straightforward.
• Naturally Parallel : We independently merge subarrays that makes it suitable for parallel processing.
• Disadvantages of Merge Sort:
• Space complexity: Merge sort requires additional memory to store the merged sub-arrays during the sorting process.
• Not in-place: Merge sort is not an in-place sorting algorithm, which means it requires additional memory to store the sorted
data. This can be a disadvantage in applications where memory usage is a concern.
• Slower than QuickSort in general. QuickSort is more cache friendly because it works in-place.
Quick Sort
• Quick Sort algorithm is a divide-and-conquer algorithm. It initially selects
an element as a pivot element and partitions the given array around the
picked pivot. Many different versions of quickSort pick pivot in different
ways.
• Always pick the first element as a pivot (implemented below).
• Always pick the last element as the pivot.
• Pick a random element as a pivot.
• Pick the median as a pivot.
• The key process in quickSort is the partition() process. The aim of the
partition() function is to receive an array and an element x of the array as
a pivot, put x at its correct position in a sorted array, and then put all
smaller elements (smaller than x) before x, and put all greater elements
(greater than x) after x. All this should be done in linear time i.e. Big
O(n).
•
Pseudo Code
Using Hoare’s Partition): 1) Slightly Complex to Implement 2) Most Efficient 3) Not stable
• /* low --> Starting index, high --> Ending index */ quickSort(arr[], low, high)
• {
• if (low < high)
• {
• pi = partition(arr, low, high);
• quickSort(arr, low, pi);
• quickSort(arr, pi + 1, high);
• }}
• partition(arr[], lo, hi)
• pivot = arr[lo]
• i = lo – 1 // Initialize left index
• j = hi + 1 // Initialize right index
• // Find a value in left side greater // than pivot
• do
• i=i+1
• while arr[i] < pivot
• // Find a value in right side smaller // than pivot
• do
• j--;
• while (arr[j] > pivot);
• if i >= j then
• return j
• swap arr[i] with arr[j]
#include <bits/stdc++.h>
using namespace std;
swap(arr[i], arr[j]);
}