https://www.cnblogs.com/onepixel/p/7674659.html This article is nice
https://www.bilibili.com/video/av685670?from=search&seid=1637373535603658338 This motion picture is excellent
https://www.icourse163.org/course/ZJU-93001 MOOC Zhejiang Big Data Structure Chen Yue and He Qin-ming
Bubble sort, select sort, insert sort are the three slowest and most classic sort algorithms
Quick sorting is generally believed to be the fastest known sorting for large random number columns
bubble sort
The simplest sorting algorithm is also the least efficient because it must swap before the final location is known, wasting many "swap operations"
If the list is sorted, it is best if no swap is needed during traversal, and if sorted, it can be terminated earlier. Bubbles under this modification are often referred to as short bubble sorting
Time Complexity: Average O(n^2), Worst O(n^2), Best O(n)
Spatial Complexity: O(1)
Stable
#Test input array alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #Bubble sort for i in range(len(alist)-1): for j in range(len(alist)-1-i): if alist[j] > alist[j+1]: alist[j],alist[j+1] = alist[j+1],alist[j] #Sort results output print('sorted:',alist)
Select Sort selection sort
Selective sorting improves bubble sorting by only exchanging once per iteration of the list
Time Complexity: Average O(n^2), Worst O(n^2), Best O(n^2)
Spatial Complexity: O(1)
Instable
#Test input array alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #Select Sort for i in range(len(alist)-1): least = i for j in range(i+1,len(alist)): if alist[j] < alist[least]: least = j if least != i: alist[least],alist[i] = alist[i],alist[least] #Sort results output print('sorted:',alist)
Insert sort insertion sort
It always maintains a sorted sublist at the lower position of the list, then "inserts" each new item back to the previous sublist, making the sorted sublist a larger item
Time Complexity: Average O(n^2), Worst O(n^2), Best O(n)
Spatial Complexity: O(1)
Stable
#Test input array alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #Insert Sort for i in range(1,len(alist)): j = i; while j>0 and alist[j-1]>alist[j]: alist[j-1],alist[j] = alist[j],alist[j-1] j -= 1 #Sort results output print('sorted:',alist)
Hill sort shell
It was invented by Shell in 1959. The first breakthrough in O(n^2) sorting is an improvement on simple insert sorting. Unlike insert sorting, it gives priority to elements that are farther apart, also known as "descending incremental sorting"
It is an improvement on the following two features of insert sorting: efficient operation on data that is almost sorted to achieve the efficiency of linear sorting; generally inefficient because insert sorting can only move data one bit at a time
Hill sorting improves the performance of insert sorting by dividing all elements of the comparison into zones.This allows an element to make a big step forward toward its final position at once
Gap concept, gap decreases, the last step is to insert sort, but it's almost in order now
gap is the Hill sorting core
The well-known gap set Marcin Ciura's gap sequence, gap s = [701, 301, 132, 57, 23, 10, 4, 1], but the following example uses a sequence whose array length is continuously divided by 2 as a gap s
Time Complexity: Average O(n(logn)^2), Worst O(n^2), Best O(n)
Spatial Complexity: O(1)
Instable
#Test input array alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #Shell Sort gap = len(alist)//2 while gap>0: #Sort each gap by insertion for i in range(gap,len(alist)): j = i while j>=gap and alist[j-gap]>alist[j]: alist[j-gap],alist[j] = alist[j],alist[j-gap] j -= gap gap = gap//2 #Sort results output print('sorted:',alist)
merge sort
The divide-and-conquer strategy to improve performance is a typical application of divide-and-conquer
Merge Sort is a recursive algorithm that constantly splits lists into half
Two-way merge and multiple merge
The disadvantage is that the merge process requires additional storage space
Time Complexity: Average O(nlogn), Worst O(nlogn), Best O(nlogn)
Spatial Complexity: O(n)
Stable
#Test input array alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #Merge Sort def merge_sort(ilist): def merge(left, right): result = [] while left and right: result.append((left if left[0] <= right[0] else right).pop(0)) return result + left + right if len(ilist) <= 1: return ilist mid = len(ilist) // 2 return merge(merge_sort(ilist[:mid]), merge_sort(ilist[mid:])) #Sort results output print('sorted:',merge_sort(alist))
quick sort
Same as merge sort, divide and conquer without extra storage
Is an improvement on bubble sorting
Usually significantly faster than other algorithms because its internal loops can be efficiently accomplished on most architectures
Simple versions are just as bad as merge sort and require extra storage, but you can change to in-place without extra space
Time Complexity: Average O(nlogn), Worst O(n^2), Best O(nlogn)
Spatial Complexity: O(nlogn)
Instable
#Test input array alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #Quick Sort def quick_sort(ilist): length = len(ilist) if length <= 1: return ilist else: # Use the last element as the first pivot pivot = ilist.pop() # Put elements greater than pivot in greater list # Put elements lesser than pivot in lesser list greater, lesser = [], [] for element in ilist: if element > pivot: greater.append(element) else: lesser.append(element) return quick_sort(lesser) + [pivot] + quick_sort(greater) #Sort results output print('sorted:',quick_sort(alist))
heap sort
Is an improvement on selection ordering
The algorithm designed with heap data structure approximates a complete binary tree
A heap usually solves a large root heap or a small root heap through a one-dimensional array
Time Complexity: Average O(nlogn), Worst O(nlogn), Best O(nlogn)
Spatial Complexity: O(1)
Instable
#Test input array alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] #Heap Sorting def heapify(unsorted, index, heap_size): largest = index left_index = 2 * index + 1 right_index = 2 * index + 2 if left_index < heap_size and unsorted[left_index] > unsorted[largest]: largest = left_index if right_index < heap_size and unsorted[right_index] > unsorted[largest]: largest = right_index if largest != index: unsorted[largest], unsorted[index] = unsorted[index], unsorted[largest] heapify(unsorted, largest, heap_size) def heap_sort(unsorted): n = len(unsorted) for i in range(n // 2 - 1, -1, -1): heapify(unsorted, i, n) for i in range(n - 1, 0, -1): unsorted[0], unsorted[i] = unsorted[i], unsorted[0] heapify(unsorted, 0, i) return unsorted #Sort results output print('sorted:',heap_sort(alist))