Repeatedly select the lowest/highest element from the unsorted part of the list & place it after the sorted part of the list.

Time Complexity: O(n^2) in all cases
Space Complexity: O(1)
Code
❌ Stable (default) (can me made stable)
✔️ In-place
✔️ Internal
Repeatedly swap the adjacent elements if they’re in the wrong order, bringing the highest element to the end in each iteration.

Time Complexity: O(n^2) in worst & avg, O(n) in best cases (already sorted)
Space Complexity: O(1)
Code
✔️ Stable
✔️ In-place
✔️ Internal
Iteratively insert each element of an unsorted list into its correct position in the sorted portion of the list.

Time Complexity: O(n^2) in worst & avg, O(n) in best cases (already sorted)
Space Complexity: O(1)
Code
✔️ Stable
✔️ In-place
✔️ Internal
Recursively divide the input into smaller sub-arrays and sort those & merge them back by Divide & Conquer approach.

This one of the most optimised & most used sorting algos.
Time Complexity: O(n logn)
Space Complexity: O(n)
Code
✔️ Stable
❌ In-place
✔️ Internal
Recursively pick an element as pivot and partition the array around it by placing the pivot in its correct position in the sorted array by Divide & Conquer aproach.
Time Complexity: O(n logn) in best cases, O(n^2) is worst & avg (poor choice of pivot)
Space Complexity: O(1) excluding stack space
Code
❌ Stable
✔️ In-place
✔️ Internal
An optimization over selection sort where we repetitively select the max element and then here we swap it with the last element and repeat the process for the list before the last element. We use Binary Heap to find the max element: O(logn) instead of generic O(n) method.

