0% found this document useful (0 votes)
2 views

Sorting (1)

The document provides an overview of three sorting algorithms: Insertion Sort, Merge Sort, and Quick Sort. It details the steps, coding implementations, time and space complexities, advantages, and disadvantages of each algorithm. Additionally, it discusses the applications of these sorting methods in various scenarios.

Uploaded by

2212087
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Sorting (1)

The document provides an overview of three sorting algorithms: Insertion Sort, Merge Sort, and Quick Sort. It details the steps, coding implementations, time and space complexities, advantages, and disadvantages of each algorithm. Additionally, it discusses the applications of these sorting methods in various scenarios.

Uploaded by

2212087
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 20

Sorting

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

• Consider an array having elements : {23, 1, 10,


5, 2}
Contd..
• Initial:
• Current element is 23
• The first element in the array is assumed to be sorted.
• The sorted part until 0th index is : [23]
• First Pass:
• Compare 1 with 23 (current element with the sorted part).
• Since 1 is smaller, insert 1 before 23 .
• The sorted part until 1st index is: [1, 23]
• Second Pass:
• Compare 10 with 1 and 23 (current element with the sorted part).
• Since 10 is greater than 1 and smaller than 23 , insert 10 between 1 and 23 .
• The sorted part until 2nd index is: [1, 10, 23]
• Third Pass:
• Compare 5 with 1 , 10 , and 23 (current element with the sorted part).
• Since 5 is greater than 1 and smaller than 10 , insert 5 between 1 and 10
• The sorted part until 3rd index is : [1, 5, 10, 23]
• Fourth Pass:
• Compare 2 with 1, 5, 10 , and 23 (current element with the sorted part).
• Since 2 is greater than 1 and smaller than 5 insert 2 between 1 and 5 .
• The sorted part until 4th index is: [1, 2, 5, 10, 23]
• Final Array:
• The sorted array is: [1, 2, 5, 10, 23]
Coding
• void insertionSort(int arr[], int n)
• {
• for (int i = 1; i < n; ++i)
• {
• int key = arr[i];
• int j = i - 1;
• /* Move elements of arr[0..i-1], that are greater than key, to one position ahead of their
current position */
• while (j >= 0 && arr[j] > key)
• {
• arr[j + 1] = arr[j];
• j = j - 1;
• }
• arr[j + 1] = key;
• }
• }
Time complexity
• Time Complexity of Insertion Sort
• Best case: O(n) , If the list is already sorted, where
n is the number of elements in the list.
• Average case: O(n 2 ) , If the list is randomly ordered
• Worst case: O(n 2 ) , If the list is in reverse order
• Space Complexity of Insertion Sort
• Auxiliary Space: O(1), Insertion sort
requires O(1) additional space, making it a space-
efficient sorting algorithm.
Contd..
• Advantages of Insertion Sort:
• Simple and easy to implement.
• Stable sorting algorithm.
• Efficient for small lists and nearly sorted lists.
• Space-efficient.
• Adoptive. the number of inversions is directly proportional to number of swaps. For example, no swapping
happens for a sorted array and it takes O(n) time only.
• Disadvantages of Insertion Sort:
• Inefficient for large lists.
• Not as efficient as other sorting algorithms (e.g., merge sort, quick sort) for most cases.
• Applications of Insertion Sort:
• Insertion sort is commonly used in situations where:
• The list is small or nearly sorted.
• Simplicity and stability are important.
• Used as a subroutine in Bucket Sort
• Can be useful when array is already almost sorted (very few inversions)
• Since Insertion sort is suitable for small sized arrays, it is used in Hybrid Sorting algorithms along with other
efficient algorithms like Quick Sort and Merge Sort. When the subarray size becomes small, we switch to
insertion sort in these recursive algorithms. For example IntroSort and TimSort use insertions sort.
Merge Sort
• Merge Sort is a sorting algorithm that uses the
divide and conquer approach.
• Divide the unsorted array into subarray, each
containing a single element.
• Take adjacent pairs of two single-element array
and merge them to form an array of 2
elements.
• Repeat the process till a single sorted array is
obtained.
Merge sort
https://opendsa-server.cs.vt.edu/embed/
mergesortAV
mergesort( array,length ) Pseudocode
// array – List of the elements to be sorted.
// length – Length of the array, i.e., the number of elements in the list.
begin
if ( length == 1 ) return array
var array1 as array = a[0] ... a[length/2] while ( a has elements )
var array2 as array = a[length/2+1] ... a[length] add a[0] to the end of c
array1 = mergesort(array1) remove a[0] from a
array2 = mergesort(array2) end while
return merge( array1, array2 )
end while ( b has elements )
merge(array1, array2 ) add b[0] to the end of c
// array1 – First array remove b[0] from b
// array2 – Second array end while
begin
var c as an array return c
while ( a and b have elements ) end
if ( array1[0] > array2[0] )
add array2 [0] to the end of c
remove array2 [0] from array2
else
add array1 [0] to the end of c
remove array1 [0] from array1
end if
end while
Coding // Merge the temp vectors back
using namespace std; // into arr[left..right]
while (i < n1 && j < n2) {
// Merges two subarrays of arr[]. if (L[i] <= R[j]) {
// First subarray is arr[left..mid] arr[k] = L[i];
// Second subarray is arr[mid+1..right] i++;
void merge(int[] arr, int left, }
int mid, int right) else {
{ arr[k] = R[j];
int n1 = mid - left + 1; j++;
int n2 = right - mid; }
k++;
// Create temp vectors }
int R[n2], L[n1]; // Copy the remaining elements of L[],
// if there are any
// Copy data to temp vectors L[] and R[] while (i < n1) {
for (int i = 0; i < n1; i++) arr[k] = L[i];
L[i] = arr[left + i]; i++;
for (int j = 0; j < n2; j++) k++;
R[j] = arr[mid + 1 + j]; }
// Copy the remaining elements of R[],
int i = 0, j = 0; // if there are any
int k = left; while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
Contd…
• // begin is for left index and end is right index
• // of the sub-array of arr to be sorted
• void mergeSort(vector<int>& arr, int left, int right)
• {
• if (left >= right)
• return;

• int mid = left + (right - left) / 2;


• mergeSort(arr, left, mid);
• mergeSort(arr, mid + 1, right);
• merge(arr, left, mid, right);
• }

• // Function to print a vector


• void printVector(vector<int>& arr)
• {
• for (int i = 0; i < arr.size(); i++)
• cout << arr[i] << " ";
• cout << endl;
• }
Complexity Analysis of Merge Sort:

• 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;

/* This function takes the first element as pivot, and places


all the elements smaller than the pivot on the left side
and all the elements greater than the pivot on /* The main function that implements QuickSort
the right side. It returns the index of the last element arr[] --> Array to be sorted,
on the smaller side */ low --> Starting index,
int partition(vector<int>& arr, int low, int high) { high --> Ending index */
int pivot = arr[low]; void quickSort(vector<int>& arr, int low, int high) {
int i = low - 1, j = high + 1; if (low < high) {

while (true) { /* pi is partitioning index, arr[pi] is now


at right place */
// Find leftmost element greater than or int pi = partition(arr, low, high);
// equal to pivot
do { // Separately sort elements before
i++; // partition and after partition
} while (arr[i] < pivot); quickSort(arr, low, pi);
quickSort(arr, pi + 1, high);
// Find rightmost element smaller than }
// or equal to pivot }
do {
j--; /* Function to print an array */
} while (arr[j] > pivot); void printArray(const vector<int>& arr) {
for (int i : arr)
// If two pointers met. cout << i << " ";
if (i >= j) cout << endl;
return j; }

swap(arr[i], arr[j]);
}

You might also like