Ten sorting algorithms (notes)

explain:

Ten sorting algorithms are implemented in Python. There is only a simple explanation and no detailed introduction of the algorithm.

Related terms:

Stable sorting: if a is in front of B, and a==b, a is still in front of B after sorting, it is a stable sorting.

Unstable sorting: if a is originally in front of b, and a==b, and a may not be in front of b after sorting, it is unstable sorting.

In place sorting: refers to the sorting process without applying for extra storage space, only using the original storage space of data to be arranged for comparison and exchange.

Non in place sorting: additional arrays are required to aid sorting.

Sorting algorithm (sorting from small to large by default):

Select sort, insert sort, bubble sort, Hill sort, merge sort, quick sort, heap sort, cardinality sort, bucket sort, cardinality sort

1. Select Sorting

Step:

1. Find the smallest element in the array

2. Swap it with the first element in the array

3. Find the smallest element among the remaining elements and exchange it with the second element in the array

4. Repeat the above operations until the entire array is sorted

def selectSort(arr):
    length = len(arr)
    for i in range(length-1):
        min_index = i
        for j in range(i+1,length):
            if arr[j] < arr[min_index]:
                min_index = j
        arr[i], arr[min_index] = arr[min_index], arr[i]
    return arr

Properties: time complexity: O(n2), space complexity: O(1), unstable sorting, in place sorting

2. Insert sort

Step:

1. Extract from the second element of the array

2. Compare it with the first element on the left. If the first element on the left is larger than it, continue to compare it with the second element on the left until an element no larger than it is encountered and insert it to the right of the element

3. Continue to extract the third, fourth and fifth n elements, repeat step 2, select the appropriate location to insert

def insertSort(arr):
    length = len(arr)
    for i in range(1,length):
        j = i - 1
        while j >= 0 and arr[j] > arr[i]:
            j -= 1
        t = arr.pop(i)
        arr.insert(j+1,t)
    return arr

Properties: time complexity: O(n2), space complexity: O(1), stable sorting, in place sorting

3. Bubble sorting

Step:

1. Compare the first element with the second element. If the first element is larger than the second, exchange their positions

2. Compare the second element with the third element. If the second element is larger than the third, exchange the position

3. Compare all the way to the last element of the array. In this way, the last element will be the maximum number after one exchange

4. Remove the last element and repeat the above operations for the remaining elements until the sorting is completed

def bubbleSort(arr):
    length = len(arr)
    for i in range(length):
        for j in range(length-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr

Properties: time complexity: O(n2), space complexity: O(1), stable sorting, in place sorting

4. Hill sorting

Step:

1. Divide the large data set into several groups, such as the first group: [0,h,2h,3h ]Group 2: [1,h+1,2h+1 ]…… (here h is the increment)

2. Insert and sort each group in turn to make the whole array part orderly

3. make h=h/2, group again, and insert and sort each group in turn

4. Repeat operation 3 until h=1, that is, the whole array is divided into a group

5. Sort this group of data

def ShellSort(arr):
    length = len(arr)
    gap = length // 2
    while gap > 0:
        for i in range(gap,length):
            insertI(arr,gap,i)
        gap = gap // 2
    return arr

def insertI(arr,gap,i):
    temp = arr[i]
    j = i - gap
    while j >= 0 and temp < arr[j]:
        arr[j+gap] = arr[j]
        j = j - gap
    arr[j+gap] = temp

Properties: time complexity: O(nlogn), space complexity: O(1), unstable sorting, in place sorting

5. Merge and sort

Step:

1. Divide the arrays to be sorted into two and arrange them separately, and then merge the two arranged arrays into an ordered array

2. The array can be divided until the size of the array is 1, and there is only one element, then the array is ordered

3. Merge two arrays of size 1 into one of size 2, and then merge the array of size 2 into one of size 4 Until all merge

def mergerSort(arr):
    n = len(arr)
    if n == 1:
        return arr
    mid = n // 2
    left = mergerSort(arr[:mid])
    right = mergerSort(arr[mid:])
    return mergeArray(left,right)

#Merge two ordered arrays
def mergeArray(arr1,arr2):
    n1 = len(arr1)
    n2 = len(arr2)
    temp = []
    i = 0
    j = 0
    while i <= n1-1 and j <= n2-1:
        if arr1[i] < arr2[j]:
            temp.append(arr1[i])
            i += 1
        else:
            temp.append(arr2[j])
            j += 1
    if i <= n1-1:
        temp.extend(arr1[i:])
    if j <= n2-1:
        temp.extend(arr2[j:])
    return temp

Properties: time complexity: O(nlogn), space complexity: O(n), stable sorting, Non-in-situ sorting

6. Quick sorting

Step:

1. Select an element of the array and call it the primary element

2. Put the elements greater than or equal to the principal element to the right of the principal element, and put the elements less than the principal element to the left of the principal element

3. The main element divides the array into two parts, using recursion, taking steps 1 and 2 for the left and right parts respectively, until the sub array has only one or zero elements

def quickSort(arr):
    return q_sort(arr, 0, len(arr)-1)

#Select the first element as the principal element
def q_sort(arr, left, right):
    if left < right:
        mid = Partition(arr, left, right)
        arr = q_sort(arr, left, mid - 1)
        arr = q_sort(arr, mid + 1, right)
    return arr

def Partition(arr, left, right):
    pivot = arr[left]
    i = left + 1
    j = right
    while i <= j:
        while i <= j and arr[i] < pivot:
            i += 1
        while i <= j and arr[j] > pivot:
            j -= 1
        if i >= j:
            break
        arr[i],arr[j] = arr[j], arr[i]
    arr[left] = arr[j]
    arr[j] = pivot
    return j

Properties: time complexity: O(nlogn), space complexity: O(logn), unstable sorting, in place sorting

7. Heap sorting

The element at the top of the heap is the maximum or minimum value of the heap. The large top heap is considered here.

Step:

1. Interchange the top element with the last element

2. After destroying the characteristics of the heap, the remaining elements form a large top heap again

3. Interchange the top element with the last second element

4. Repeat the above operations until there is one remaining element, then the sorting is completed

def headSort(arr):
    #Build heap
    length = len(arr)
    t = (length - 2) // 2
    for i in range(t,-1,-1): #Subscript does not contain-1
        downHead(arr,i,length-1)
    #Sinking after exchange for stacking
    for i in range(length-1,0,-1):
        arr[0], arr[i] = arr[i], arr[0]
        downHead(arr,0,i-1)
    return arr

def downHead(arr,parent,length):
    temp = arr[parent]
    #Left child
    child = 2 * parent + 1
    while child <= length:
        #Targeting older children
        if child + 1 <= length and arr[child+1] > arr[child]:
            child += 1
        if temp > arr[child]:
            break
        arr[parent] = arr[child]
        parent = child
        child = 2 * parent + 1
    arr[parent] = temp

Properties: time complexity: O(nlogn), space complexity: O(1), unstable sorting, in place sorting

8. Count and sort

The difference between the maximum value and the minimum value is not large

Step:

1. Find the maximum and minimum values in the array

2. Construct A continuous array A with A length of (max min + 1)

3. Count the times of each element in the array, and store it in A

4. Sum up the data in the temporary array A from small to large, and output several times in case of several times

def countSort(arr):
    min_arr = min(arr)
    max_arr = max(arr)
    len = max_arr - min_arr + 1
    temp = [0] * len
    result = []
    for t in arr:
        temp[t-min_arr] = temp[t-min_arr] + 1
    for i in range(min_arr,max_arr+1):
        p = [i]*temp[i-min_arr]
        result.extend(p)
    return result

Properties: time complexity: O(n+k), space complexity: O(k), stable sorting, non in place sorting (k is the size of temporary array)

9. Bucket sorting

When the value range of a sequence is too large, or it is not an integer, it is not applicable to count sorting

Step:

1. Create several buckets to determine the range of each bucket, which can carry one or more elements

2. Traverse the original sequence and place the element number in each bucket

3. The elements inside each bucket are sorted separately

4. Traverse all buckets and output all elements

def bucketSort(arr):
    n = len(arr)
    min_arr = min(arr)
    max_arr = max(arr)
    result = []
    #establish n Barrels
    new_list = [[] for _ in range(n)]
    #Interval span size
    length = (max_arr - min_arr) // (n - 1)
    for data in arr:
        index = int((data - min_arr) // (length + 1))
        new_list[index].append(data)
    for i in range(n):
        new_list[i].sort()
    for i in range(n):
        for j in range(len(new_list[i])):
            result.append(new_list[i][j])
    return result

Properties: time complexity: O(n+k), space complexity: O(n+k), stable sorting, Non-in-situ sorting (k is the number of barrels)

10. Cardinality sorting

Step:

1. Sort the data by the size of single digits, then by the size of ten digits, then by the number of hundreds

2. When sorting by a certain number of digits, you need to prepare 10 buckets of 0-9, and put the same number in the same bucket

def radioSort(arr):
    #Calculate the maximum number of digits
    num = 1
    max_arr = max(arr)
    while max_arr // 10 > 0:
        max_arr = max_arr // 10
        num += 1
    for i in range(1,num+1):
        bucket = [[] for _ in range(10)]
        for j in range(len(arr)):
            radio = (arr[j] // int(pow(10,i-1))) % 10
            bucket[radio].append(arr[j])
        k = 0
        for i in range(10):
            for j in range(len(bucket[i])):
                arr[k] = bucket[i][j]
                k += 1
    return arr

Properties: time complexity: O (k n), space complexity: O(n+k), stable sorting, Non-in-situ sorting (k is the number of barrels)

Tags: Python less

Posted on Sun, 14 Jun 2020 01:03:51 -0400 by tazz