Eight common sorting algorithms

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) 

Posted on Thu, 25 Nov 2021 18:47:50 -0500 by CodeMama