Data Structure and Algorithm 3 | Sorting Algorithms

0_QXrDY4nVmhZ1umbX

1. General Sorting Algorithms

(1) Selection Sort

Select the minimum value in an array, then put it to the front.

Time complexity .

(2) Insertion Sort

Traverse each value, put it forward if the former one is smaller until the former one is larger.

Time complexity .

(3) Exchange Sort

Traverse each key in the array, swap if the key and the following key pairs are unordered. Note that this is different from bubble sort.

Time complexity .

(4) Bubble Sort: Baseline

Select each pair of keys, swap them if the former one is larger than the later one. Remember the last i keys must be sorted in the iteration so that we can skip them.

Time complexity .

(5) Bubble Sort: Optimized

In the bubble sort, we can stop early when there's no more swaps in one iteration, which means the rest of the array is already sorted. We can add a swapped variable to show if we need to go to the next iteration.

Time complexity .

Screen Shot 2022-03-10 at 9.27.28 PM

(6) Merge Sort

Merge sort is a divide and conquer solution which first divide the array into pairs. Then we sort these pairs and finally merge these sorted arrays together with mergeTwoSortedArray function of time complexity of .

In general, this sorting technique has a time complexity of .

Here is an example of mergeTwoSortedArray function with time complexity of .

(7) Quick Sort

Quick sort is another divide and conquer algorithm. The idea of quick sort is to select one key as pivot, then put all the keys smaller than it on its left, and put all the other keys on its right by function partition. Then we continue this process for the left and right part until we get a sorted array.

There are many ways to perform the partition. Here is a naive solution of time complexity .

Or we can also use the following partition function for partition with ime complexity , where . This method is called Lomuto partition scheme.

2. Heuristic Sorting Algorithms

Let's say we know some domain knowledge of the keys we have in the array, then we can develop some heuristic sorting algorithms that is much much faster than the general theorical limition .

(1) Sorting Non-negative Integers: Pigeonhole

The idea is very simple. It is like we first count the amout of each integer we have in the list. And then we output the integers in the order from low to high with repeating times we calculated. So this is not actually sorting.

Time complexity is .

Note that when we have a short array with an extraordinary large maximum value, we are going to experience a huge cost of the space complexity and the algorithm will become super slow!

(2) Sorting Non-negative Integers: Bucket Sort

To deal with the problem of pigeonhole, we can use a hashtable like data structure to store the keys. The difference is that these buckets actually have an order that we can directly join the sorted keys in each bucket to get a sorted result. The worst time complexity is and the average time complexity is .

(3) Sorting Strings: Bucket Sort

Bucket sort can also be used to sort a string array. It is similar to a hashtable with index of letters. The problem is that if we have all the words start with the same letter in an array, this data structure will be useless. In order to deal with this problem, we will introduce trie structure in the next section.