常用六大排序算法的python实现

总是不能在网络上找到完整正确简洁的排序算法的python写法, 还是自己写一篇作为归纳.
下列方法都经过测试
测试方法:

import random
#生成随机数组
a = [random.randint(0,1000) for _ in range(100)]
#执行排序
sortfunc(a)
#判断结果
bool(a == sorted(a)) 
#若为降序排序则为bool(a == sorted(a,reverse=True))

1.选择排序

def selectsort(a):
    for i in range(len(a)-1):
        for j in range(i+1,len(a)):
            if a[j] < a[i]:
                a[i],a[j] = a[j],a[i]

记忆点:遇到比i位小的数,交换两个值,每一趟找出第i小的数
时间复杂度:O(n*n)

2.插入排序

def insort(a):
    for i in range(1,len(a)):
        key = a[i]
        for j in range(i-1,-1,-1):
            if a[j] > key:
                a[j],a[j+1] = a[j+1],a[j]

时间复杂度:O(n*n)

3.冒泡排序

def bubble(a):
    swapped = False
    for i in range(len(a),0,-1):
        for j in range(i-1):
            if a[j+1] < a[j]:
                a[j],a[j+1] = a[j+1],a[j]
                swapped = True
        if not swapped:
            break

时间复杂度: O(n*n)
记忆点:
1) 冒泡第i趟可以确保最左(或最右,取决于实现)i个值为最正确顺序;
2) 加入swapped可以判断最好的情况,即数组已经排好序,时间复杂度降为O(n)

4.快速排序

def qsort(a,l,r):
    if l < r:
        p = a[r]
        i = l - 1
        for j in range(l,r):
            if a[j] <= p:
                i += 1
                a[i],a[j] = a[j],a[i]
        i += 1
        a[i],a[r] = a[r],a[i]
        qsort(a,l,i-1)
        qsort(a,i+1,r)

python快速排序的各种实现方法中有更详细一些的表述.
时间复杂度: O(nlogn),在每次选到的主元(pivot)都为当前数组最大或最小值时,算法退化到O(n*n).

5.归并排序

def merge(left, right):
    res = []
    while left and right:
        if left[0] < right[0]:
            res.append(left.pop(0))
        else:
            res.append(right.pop(0))
    if left:
        res.extend(left)
    else:
        res.extend(right)
    return res

def mergesort(lists):
    if len(lists) <= 1:
        return lists
    mid = len(lists)//2
    left = mergesort(lists[:mid])
    right = mergesort(lists[mid:])
    return merge(left,right)

6.堆排序

def adjust_heap(a,i,size):
    if i <= (size-2)//2:
        l = 2*i + 1 #左结点
        r = 2*i + 2 #右结点
        m = i
        if l < size and a[l] > a[m]:
            m = l
        if r < size and a[r] > a[m]:
            m = r
        if m != i:
            #若子节点比根节点大,则交换结点
            a[m],a[i] = a[i],a[m]
            #交换后不能保证位于子节点位置的原本的"根节点"符合堆性质,继续调整
            adjust_heap(a,m,size)

def build_heap(a):
    size = len(a)
    #倒数第一个下标为size-1,((size-1)-1)//为最后一个非叶节点
    for i in range((size-2)//2,-1,-1):
        adjust_heap(a,i,size)

def heapsort(a):
    size = len(a)
    #建堆
    build_heap(a)
    for i in range(size-1,0,-1):
        #大顶堆性质:a[0]必为每次排序的最大值,将其放到数组后面
        a[0],a[i] = a[i],a[0]
        adjust_heap(a,0,i)

猜你喜欢

转载自blog.csdn.net/m0_37422289/article/details/80499866