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
Related Articles