# 1 time complexity and space complexity of eight sorting algorithms

Sorting algorithm | stability | Average time complexity | Worst time complexity | Spatial complexity | remarks |
---|---|---|---|---|---|

Heap sort | instable | O(nlogn) | O(nlogn) | O(1) | When n is large, it is better |

Quick sort | instable | O(nlogn) | O(n^2) | O(nlogn) | n is good when it is large |

Shell Sort | instable | O(nlogn) | O(n^s) | O(1) | Group selected when s |

Select sort | instable | O(n^2) | O(n^2) | O(1) | When n is small, it is better |

Cardinality sort | stable | O(logRB) | O(logRB) | O(n) | B is the true number (0 -- 9), and R is the cardinality |

Bubble sorting | stable | O(n^2) | O(n^2) | O(1) | n hours is better |

Insert sort | stable | O(n^2) | O(n^2) | O(1) | Better when most are sorted |

Merge sort | stable | O(nlogn) | O(nlogn) | O(1) | When n is large, it is better |

- Stability of sorting algorithm

It is assumed that there are multiple records with the same keyword in the record sequence to be sorted. If the records are sorted, the relative order of these records remains unchanged, that is, in the sequence, A1=A2 and before A1 word A2, while in the sorted sequence, A1 is before A2, then this sorting algorithm is said to be stable, otherwise it becomes unstable.

# 2. python implementation of sorting algorithms

## 2.1 bubble sorting (stable)

nums = [1,3,1,4,5,9,12,1,11,135,12,3,45,67,89,23] def bubbleSort(arr): n = len(arr) for i in range(n): for j in range(0,n-i-1): if arr[j]>arr[j+1]: arr[j],arr[j+1] = arr[j+1],arr[j] return arr bubbleSort(nums)

## 2.2 merge sort (stable)

def merge(list_left,list_right): l,r = 0,0 new_list = [] while l < len(list_left) and r<len(list_right): if list_left[l] <= list_right[r]: new_list.append(list_left[l]) l += 1 else: new_list.append(list_right[r]) r += 1 new_list += list_left[l:] new_list += list_right[r:] return new_list def mergeSort(arr): if len(arr) <= 1: return arr mid = len(arr)//2 list_left = mergeSort(arr[:mid]) list_right = mergeSort(arr[mid:]) return merge(list_left,list_right) arr = [12,33,15,11,1,1334,122234] res = mergeSort(arr) print(res)

## 2.3 insert sort (stable)

def insertSort(arr): for i in range(len(arr)): preIndex = i - 1 current = arr[i] while preIndex >=0 and arr[preIndex] > current: arr[preIndex+1]=arr[preIndex] preIndex -=1 arr[preIndex+1] = current return arr nums = [1,4,7,2,5,8,3,6,9,0] insertSort(nums)

## 2.4 cardinality sorting (stable)

def radixSort(arr): n = len(str(max(arr))) for k in range(n): bucket_list = [[] for i in range(10)] for i in arr: bucket_list[i//(10**k)%10].append(i) arr = [j for i in bucket_list for j in i] return arr

## 2.5 selection sorting (unstable)

Algorithm flow:

First, find the smallest (large) element in the unordered sequence and store it at the beginning of the sorted sequence.

Then continue to find the smallest (large) element from the remaining unordered elements, and then put it at the end of the sorted sequence.

Repeat step 2 until all elements are sorted.

def selectionSort(arr): for i in range(len(arr)-1): minIndex = i # Record the index of the smallest number for j in range(i+1,len(arr)): if arr[j]<arr[minIndex]: minIndex = j if i!= minIndex: arr[i],arr[minIndex] = arr[minIndex],arr[i] return arr nums = [1,4,7,2,5,8,3,6,9,0] selectionSort(nums)

## 2.6 quick sort (unstable)

def quickSort(arr,i,j): if i >= j: return [] pivot = arr[i] # Based on the first element low = i high = j while i < j: while i<j and arr[j]>=pivot: j -= 1 arr[i] = arr[j] while i<j and arr[i] <= pivot: i += 1 arr[j] = arr[i] arr[j] = pivot quickSort(arr,low,i-1) quickSort(arr,i+1,high) return arr

## 2.7 Hill sorting

def shellSort(arr): n = len(arr) gap = int(n/2) while gap > 0: for i in range(gap,n): temp = arr[i] j = i while j >= gap and arr[j-gap] > temp: arr[j] = arr[j-gap] j -= gap arr[j] = temp gap = int(gap/2) return arr

## 2.8 heap sorting

Heap sort is a sort algorithm designed by using the data structure of heap. Heap is a structure similar to a complete binary tree and satisfies the nature of heap: that is, the key value or index of a child node is always less than (or greater than) its parent node. Heap sort can be said to be a selective sort that uses the concept of heap to sort.

def heapify(arr, n, i): largest = i l = 2 * i + 1 # left = 2*i + 1 r = 2 * i + 2 # right = 2*i + 2 if l < n and arr[i] < arr[l]: largest = l if r < n and arr[largest] < arr[r]: largest = r if largest != i: arr[i],arr[largest] = arr[largest],arr[i] # exchange # At this time, the number of the largest position (that is, the lis[i] input at the beginning) is in the pending state, and its position needs to be determined in all its roots heapify(arr, n, largest) def heapSort(arr): n = len(arr) # Build a maxheap. for i in range(n, -1, -1): # First adjust the heap to the state of the small root heap, and adjust the position of each number one by one in the whole heap. The adjustment method is to determine its position in all its roots heapify(arr, n, i) # Exchange elements one by one for i in range(n-1, 0, -1): arr[i], arr[0] = arr[0], arr[i] # exchange # Arrange the new 0 to the appropriate position, where i refers to the range of the heap to be adjusted heapify(arr, i, 0)