- Bubble Sort
- Insertion Sort
- Selection Sort
- Cycle Sort
- AKA Sinking sort/ Exchange sort
- In-place, stable
- Space complexity constant O(1)
- Time complexity:
- Best case - O(n)
- Worst case - O(n2)
algo:
- Set two counters - Outer loop for
0 to (n - 1)
times as the last remaining element doesn't need further check - Inner loop from 1 to
(arr.length - i)
times (as last places don't need check) - swap adjacent ele if greater. (
if j < j-1:
swap) - If already sorted, j never swaps (best case):
- raise a flag
swapped
before the inner loop. - In the if condition, make it
true
. - After the inner loop completes, if
(!swapped) break;
- raise a flag
- In bubble sort, we compare the adjacent elements and replace the greater one to last (right if sorting for ascending)
- With each pass, the largest element comes at the end.
-
Space complexity : O(1)
-
Best case time complexity : O(n)
In best case, the array is already sorted. In this case, the inner pointer never swaps. Hence outer loop runs only once and inner loop run for n times. -
Worst case time complexity :
In the worst case, the array is inversely sorted. Here, the inner loop is run for (n-1) times and these inner loops run for (n - 1) times.Therefore, if the array is of length 4, and inversely sorted, the loop run is like: ---------pass 1 : i = 0 [4,3,2,1] 3,4,2,1 3,2,4,1 3,2,1,4 👈 pass 1 completes | n = 3 ------------ i = 1 (next iteration of outer loop) 2,3,1,4 2,1,3,4 👈 pass 2 completes | n = 2 ------------ i = 2 1,2,3,4 👈 pass 3 completes | n = 1 ------------ i = 3 outer loop ends (as set for arr.length - 1 times) Total number of comparisons = (n - 1) * (n - 1) = n**2 - 2n + 1 OR no. of comparisons = (n - 1) + (n - 2) (n - 3) = 3n - (1+2+3) = 3n - (n*(n+2) / 2) = 3m - (n**2 + n)/2 = (6n - n**2 - n)/ 2 Therefore O(n2)
Code
function bubbleSort(arr) {
let swapped = false;
for (let i = 0; i < arr.length; i++) {
for (let j = 1; j < arr.length - i; j++) {
if (arr[j] < arr[j - 1]) {
let temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
swapped = true;
}
}
if (!swapped) break;
}
}
- In-place, non-stable
- Use case : Performs well in small size lists. arrays
- Space complexity constant O(1)
- Time complexity:
- Best case - O(n2)
- Worst case - O(n2)
algo:
- We need to loop over the entire array. For loop from
i=0; i<arr.length
- Set the
lastIndex
variable. This will bearr.length - 1 - i
asi
starts from 0, and we don't need last variable for the last iteration. - Set a
maxIndex
variable so that we can swap it with thelastIndex
variable. - Create a
getMaxIndexInRange
method which takes an array, and two index numbers and returns the max index of the range. - In the for loop, swap
lastIndex
withmaxIndex
- In selection sort, we simply swap max ele in the range with the last index. This range is full length initially, and with each iteation, it gets reduced by 1.
- Since we select the max (or min) and swap with the last (or first in case of min) place, we call it Selection sort.
-
Space complexity : O(1)
-
Best case time complexity : O(n2)
In best case, even if the array is already sorted, we check the biggest in the range and replace it with the last. So, there's no difference in worst and best case complexities. -
Worst case time complexity :
In the worst case, the array is inversely sorted. Here, the inner loop is run for (n-1) times and these inner loops run for (n - 1) times.Therefore, if the array is of length 4, and inversely sorted, the loop run is like: ---------pass 1 : i = 0 [4,3,2,1] 1,3,2,4 1,2,3,4 no. of comparisons = (n - 1) + (n - 2) + (n - 3) = 3n - (1+2+3) = 3n - (n*(n+2) / 2) = 3m - (n**2 + n)/2 = (6n - n**2 - n)/ 2 Therefore O(n2)
Code
function selectionSort(arr) {
for (let i = 0; i < arr.length; i++) {
let lastIndex = arr.length - i - 1;
let maxIndexInRange = getMaxIndexInRange(arr, 0, last);
swap(arr, maxIndexInRange, lastIndex);
}
function swap(arr, first, second) {
let temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
}
function getMaxIndexInRange(arr, startIndex, endIndex) {
let maxIndexInRange = startIndex;
for (let i = startIndex; i <= endIndex; i++) {
if (arr[i] > arr[maxIndexInRange]) {
maxIndexInRange = i;
}
}
return maxIndexInRange;
}
}
- In-place, stable
- Use case : Small size partially sorted arrays (Benefit : steps are reduced)
- Space complexity constant O(1)
- Time complexity:
- Best case - O(n)
- Worst case - O(n2)
- For
i = 0
startj = i+1
i
will run from0
ton-2
(including)j
has to be greater than0
- Break when
j
is not smaller thanj-1
algo
- Loop from
i=0
to (including)n-2
- In the inner loop,
j
will approach from the right to left.j
will check if theele[j]
is less greater than ele at LHS and break when it sees a number that is greater thanele[j]
. j
should not exceed 0.
- In insertion sort, we sort the array partially.
- The idea is to take ele[i1] and insert it in its correct position in the (sorted) LHS part
-
Space complexity : O(1)
-
Best case time complexity : O(n)
In best case, arr[j] checks forarr[j] < arr[j-1]
and breaks. i++ and continues. This is time complexity of O(n). -
Worst case time complexity :
In the worst case, the array is inversely sorted. Here, the inner loop is run for (n-1) times and these inner loops run for (n - 1) times.Therefore, if the array is of length 4, and inversely sorted, the loop run is like: ---------pass 1 : i = 0 [4,3,2,1] 3,4,2,1 2,3,4,1 1,2,3,4 no. of comparisons = (n - 1) + (n - 2) + (n - 3) = 3n - (1+2+3) = 3n - (n*(n+2) / 2) = 3m - (n**2 + n)/2 = (6n - n**2 - n)/ 2 Therefore O(n2)
Code
function insertionSort(arr) {
for (let i = 0; i <= arr.length - 2; i++) {
for (let j=i+1; j > 0; j--) {
if (arr[j] < arr[j-1]) {
let temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
} else {
break;
}
}
}
- In-place, non-stable
- Use case :When given nos are in range 1 - n
- Space complexity constant O(1)
- Time complexity:
- Best case - O(n)
- Worst case - O(n)
algo
- while loop. Set i=0 outside.
- Inside while loop, let
correctIndex = arr[i]-1
- If arr[i]!=arr[correctIndex], swap(i,correct) else i++
- In cyclic sort, we deal with numbers from 1 to n or 0 to n. The ideal position of the number (elements) is either arr[i]-1 or arr[i]. Set
correctIndex
to it's respective position,
-
Space complexity : O(1)
-
Best case time complexity : O(n)
In the best case, there's n-1 number of comparisons. Therefore, O(n) -
Worst case time complexity :
In the worst case,[3, 5, 2, 1, 4] <-- is arr[0]==arr[ideal]? no -> swap 1 swap [2, 5, 3, 1, 4] 1 swap [5, 2, 3, 1, 4] 1 swap [4, 2, 3, 1, 5] 1 swap [1, 2, 3, 4, 5] 1 swap total number of swaps = total number of ele = n Total comparisons = (n-1) Thus total = (n-1) + n = 2n-1 Therefore time complexity is O(n)
Code
function cyclicSort(arr) {
let i = 0;
while (i < arr.length) {
let correctIndex = arr[i] - 1;
if (arr[i] != arr[correctIndex]) {
let temp = arr[i];
arr[i] = arr[correctIndex];
arr[correctIndex] = temp;
} else {
i++;
}
}
}