Sorting algorithm (Hill sorting, quick sorting, merge sorting (moving image analysis))

Hill sort

Hill sort (Shell Sort) is a kind of insertion sort. Also known as reduced incremental sort, it is a more efficient and improved version of the direct insertion sort algorithm. Hill sorting is an unstable sorting algorithm.
The basic idea of ​​Hill sorting is : list the array in a table and insert and sort the columns separately, repeat this process, but use a longer column each time (the step length is longer, the number of columns is fewer) . In the end, the entire table has only one column. Converting the array to the table is to better understand the algorithm, and the algorithm itself still uses arrays for sorting .

Analysis of Algorithms

Insert picture description here

// An highlighted block
'''希尔排序'''
def shell_sort(alist):
    n = len(alist)
    # gap为步长,选择gap值的元素进行判断
    gap = n // 2
    #gap值减少为1时,外部循环停止
    while gap > 0:
        # 按步长进行插入排序
        for j in range(gap, n):
            #第一层的数据进行排序后,然后下一层的值为gap+1位置的值
            i = j
            # 将gap位置的值与前gap的值相比较,进行排序
            while i>0:
                if alist[i]<alist[i-gap]:
                    alist[i],alist[i - gap] =alist[i - gap],alist[i]
                    i -= gap
                else:
                    break
        # 得到新的步长
        gap = gap // 2

li = [11,13,5,7,20]
a=[11,13,5,33,4,17,7,20,9,15,10,50]
shell_sort(li)
print(li)
shell_sort(a)
print(a)

Insert picture description here

time complexity

Optimal time complexity: different according to the step sequence.
Worst time complexity: O(n^2)
stable thinking: unstable

Quick sort

Quick sort (English: Quicksort), also known as partition-exchange sort (partition-exchange sort), divides the data to be sorted into two independent parts through a sorting, all data in one part is smaller than all data in the other part , And then quickly sort the two parts of the data according to this method. The entire sorting process can be recursively performed so that the entire data becomes an ordered sequence.

Analysis of Algorithms

Insert picture description here

// An highlighted block
"""快速排序"""
def quick_sort(alist, start, end):
    # 递归的退出条件
    if start >= end:
        return
    # 设定起始元素为要寻找位置的基准元素
    mid = alist[start]
    # low为序列左边的由左向右移动的游标
    low = start
    # high为序列右边的由右向左移动的游标
    high = end
    len(alist)
    while low < high:
        # 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动
        while low < high and alist[high] >= mid:
            high -= 1
        # 将high指向的元素放到low的位置上
        alist[low] = alist[high]
        # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动
        while low < high and alist[low] < mid:
            low += 1
        # 将low指向的元素放到high的位置上
        alist[high] = alist[low]
    # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置
    # 将基准元素放到该位置
    alist[low] = mid
    # 对基准元素左边的子序列进行快速排序
    quick_sort(alist, start, low-1)
    # 对基准元素右边的子序列进行快速排序
    quick_sort(alist, low+1, end)

alist = [20,13,5,7,11,30,3,65,45]
quick_sort(alist,0,len(alist)-1)
print(alist)

Insert picture description here

time complexity

Optimal time complexity: O(nlogn)
Worst time complexity: O(n^2)
Stability: Unstable

Merge sort

Merge sorting is a very typical application of divide and conquer. The idea of ​​merge sort is to decompose the array recursively first, and then merge the array.
After decomposing the array to the smallest size, and then merging the two ordered arrays, the basic idea is to compare the first number of the two arrays, and take the one who is smaller first, and then move the corresponding pointer back one bit after taking the number. Then compare until one array is empty, and finally copy the rest of the other array.

Analysis of Algorithms

The final algorithm principle analysis is the same, so I wrote a part
Insert picture description here

// An highlighted block
def merge_sort(alist):
    if len(alist) <= 1:
        return alist
    # 二分分解
    num = len(alist)//2
    left = merge_sort(alist[:num])
    right = merge_sort(alist[num:])
    # 合并
    return merge(left,right)

def merge(left, right):
    '''合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组'''
    #left与right的下标指针
    l, r = 0, 0
    result = []
    while l<len(left) and r<len(right):
        if left[l] < right[r]:
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    return result

alist = [54,26,93,17,77,31,44,55,20]
sorted_alist = merge_sort(alist)
print(sorted_alist)

Insert picture description here

time complexity

Optimal time complexity: O(nlogn)
Worst time complexity: O(nlogn)
Stability: stable

Comparison of the efficiency of common sorting algorithms

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_42567027/article/details/107115455