 Open in App
Not now

# Lower bound for comparison based sorting algorithms

• Difficulty Level : Easy
• Last Updated : 24 Jan, 2023

The problem of sorting can be viewed as following.
Input: A sequence of n numbers <a1, a2, . . . , an>.
Output: A permutation (reordering) <a1, a2, . . . , an> of the input sequence such that a1 <= a2 ….. <= a’n
A sorting algorithm is comparison based if it uses comparison operators to find the order between two numbers.  Comparison sorts can be viewed abstractly in terms of decision trees. A decision tree is a full binary tree that represents the comparisons between elements that are performed by a particular sorting algorithm operating on an input of a given size. The execution of the sorting algorithm corresponds to tracing a path from the root of the decision tree to a leaf. At each internal node, a comparison ai <= aj is made. The left subtree then dictates subsequent comparisons for ai <= aj, and the right subtree dictates subsequent comparisons for ai > aj. When we come to a leaf, the sorting algorithm has established the ordering. So we can say following about the decision tree.
1) Each of the n! permutations on n elements must appear as one of the leaves of the decision tree for the sorting algorithm to sort properly.
2) Let x be the maximum number of comparisons in a sorting algorithm. The maximum height of the decision tree would be x. A tree with maximum height x has at most 2^x leaves.
After combining the above two facts, we get following relation.

```
n!  <= 2^x

Taking Log on both sides.
log2(n!)  <= x

Since log2(n!)  = Θ(nLogn),  we can say
x = Ω(nLog2n)```

Therefore, any comparison based sorting algorithm must make at least nLog2n comparisons to sort the input array, and Heapsort and merge sort are asymptotically optimal comparison sorts.
Example :

## Python3

 `def` `merge_sort(arr):``    ``if` `len``(arr) > ``1``:``        ``# Divide the array into two halves``        ``mid ``=` `len``(arr) ``/``/` `2``        ``left ``=` `arr[:mid]``        ``right ``=` `arr[mid:]` `        ``# Recursively sort the two halves``        ``merge_sort(left)``        ``merge_sort(right)` `        ``# Merge the sorted halves``        ``i ``=` `j ``=` `k ``=` `0``        ``while` `i < ``len``(left) ``and` `j < ``len``(right):``            ``if` `left[i] < right[j]:``                ``arr[k] ``=` `left[i]``                ``i ``+``=` `1``            ``else``:``                ``arr[k] ``=` `right[j]``                ``j ``+``=` `1``            ``k ``+``=` `1` `        ``# Copy any remaining elements``        ``while` `i < ``len``(left):``            ``arr[k] ``=` `left[i]``            ``i ``+``=` `1``            ``k ``+``=` `1``        ``while` `j < ``len``(right):``            ``arr[k] ``=` `right[j]``            ``j ``+``=` `1``            ``k ``+``=` `1` `arr ``=` `[``5``, ``2``, ``4``, ``6``, ``1``, ``3``]``merge_sort(arr)``print``(arr)`

## Java

 `public` `class` `MergeSort {``  ``public` `static` `void` `mergeSort(``int``[] arr) {``    ``if` `(arr.length > ``1``) {``      ``// Divide the array into two halves``      ``int` `mid = arr.length / ``2``;``      ``int``[] left = Arrays.copyOfRange(arr, ``0``, mid);``      ``int``[] right = Arrays.copyOfRange(arr, mid, arr.length);` `      ``// Recursively sort the two halves``      ``mergeSort(left);``      ``mergeSort(right);` `      ``// Merge the sorted halves``      ``int` `i = ``0``, j = ``0``, k = ``0``;``      ``while` `(i < left.length && j < right.length) {``        ``if` `(left[i] < right[j]) {``          ``arr[k] = left[i];``          ``i++;``        ``} ``else` `{``          ``arr[k] = right[j];``          ``j++;``        ``}``        ``k++;``      ``}` `      ``// Copy any remaining elements``      ``while` `(i < left.length) {``        ``arr[k] = left[i];``        ``i++;``        ``k++;``      ``}``      ``while` `(j < right.length) {``        ``arr[k] = right[j];``        ``j++;``        ``k++;``      ``}``    ``}``  ``}` `  ``public` `static` `void` `main(String[] args) {``    ``int``[] arr = {``5``, ``2``, ``4``, ``6``, ``1``, ``3``};``    ``mergeSort(arr);``    ``System.out.println(Arrays.toString(arr));``  ``}``}`

## C++

 `#include ``#include ` `void` `mergeSort(``int``* arr, ``int` `left, ``int` `right) {``  ``if` `(left < right) {``    ``// Divide the array into two halves``    ``int` `mid = (left + right) / 2;` `    ``// Recursively sort the two halves``    ``mergeSort(arr, left, mid);``    ``mergeSort(arr, mid + 1, right);` `    ``// Merge the sorted halves``    ``int` `i = left, j = mid + 1, k = 0;``    ``int``* temp = ``new` `int``[right - left + 1];``    ``while` `(i <= mid && j <= right) {``      ``if` `(arr[i] < arr[j]) {``        ``temp[k] = arr[i];``        ``i++;``      ``} ``else` `{``        ``temp[k] = arr[j];``        ``j++;``      ``}``      ``k++;``    ``}` `    ``// Copy any remaining elements``    ``while` `(i <= mid) {``      ``temp[k] = arr[i];``      ``i++;``      ``k++;``    ``}``    ``while` `(j <= right) {``      ``temp[k] = arr[j];``      ``j++;``      ``k++;``    ``}` `    ``// Copy the sorted array back to the original array``    ``for` `(i = left; i <= right; i++) {``      ``arr[i] = temp[i - left];``    ``}``    ``delete``[] temp;``  ``}``}` `int` `main() {``  ``int` `arr[] = {5, 2, 4, 6, 1, 3};``  ``mergeSort(arr, 0, 5);``  ``for` `(``int` `i = 0; i < 6; i++) {``    ``std::cout << arr[i] << ``" "``;``  ``}``  ``std::cout << std::endl;``  ``return` `0;``}`

## Javascript

 `function` `mergeSort(arr) {``  ``if` `(arr.length > 1) {``    ``// Divide the array into two halves``    ``let mid = Math.floor(arr.length / 2);``    ``let left = arr.slice(0, mid);``    ``let right = arr.slice(mid, arr.length);` `    ``// Recursively sort the two halves``    ``mergeSort(left);``    ``mergeSort(right);` `    ``// Merge the sorted halves``    ``let i = 0, j = 0, k = 0;``    ``while` `(i < left.length && j < right.length) {``      ``if` `(left[i] < right[j]) {``        ``arr[k] = left[i];``        ``i++;``      ``} ``else` `{``        ``arr[k] = right[j];``        ``j++;``      ``}``      ``k++;``    ``}` `    ``// Copy any remaining elements``    ``while` `(i < left.length) {``      ``arr[k] = left[i];``      ``i++;``      ``k++;``    ``}``    ``while` `(j < right.length) {``      ``arr[k] = right[j];``      ``j++;``      ``k++;``    ``}``  ``}``}` `let arr = [5, 2, 4, 6, 1, 3];``mergeSort(arr);``console.log(arr);`

Output

`[1, 2, 3, 4, 5, 6]`

My Personal Notes arrow_drop_up