python算法之排序(二)

半城伤御伤魂 提交于 2020-02-12 22:01:46
#堆排序#基本思想:1.将初始待排序数字列表(R1,R2,...,Rn)构建成大顶堆,此堆为初始的无序列表#          2.将堆顶元素R1与最后一个元素Rn交换,此时得到新的无序列表(R1,R2,...,Rn-1)和新的有序列表(Rn)#          3.由于交换后新的堆顶R1可能违反堆的性质,因此需要对当前无序列表(R1,R2,...,Rn-1)调整为新堆,#          然后再次将R1与无序列表最后一个元素交换,得到新的无序列表(R1,R2,...,Rn-2)和新的有序列表(Rn-1,Rn).#          不断重复此过程直到有序列表的元素个数为n-1,则整个排序过程完成。#sift_down通过从下而上比较每个节点与其子节点的大小(Ri<R2i,Ri<R2i+1),将最大的数放置到堆顶def sift_down(numList, start, end):    root = start    while True:        child = 2 * root + 1        if child >end:            break        if child + 1 <=end and numList[child] < numList[child+1]:            child += 1        if numList[root] < numList[child]:            numList[root], numList[child] = numList[child], numList[root]            root = child        else:            breakdef heap_sort(numList):    #将初始列表组成大顶堆    first = len(numList) // 2 - 1    for start in reversed(range(0, first+1)):        sift_down(numList, start, len(numList)-1)    print(numList)    #将最大的数放置到最后,对前n-1个元素进行堆调整    for end in range(len(numList)-1, 0, -1):        numList[0], numList[end] = numList[end], numList[0]        sift_down(numList, 0, end-1)        print(numList)    return numListprint(heap_sort([16, 7, 3,20,17,8,99,76]))# [99, 76, 16, 20, 17, 8, 3, 7]# [76, 20, 16, 7, 17, 8, 3, 99]# [20, 17, 16, 7, 3, 8, 76, 99]# [17, 8, 16, 7, 3, 20, 76, 99]# [16, 8, 3, 7, 17, 20, 76, 99]# [8, 7, 3, 16, 17, 20, 76, 99]# [7, 3, 8, 16, 17, 20, 76, 99]# [3, 7, 8, 16, 17, 20, 76, 99]# 归并排序:# 基本思想:首先归并排序使用了二分法,归根到底的思想还是分而治之。拿到一个长数组,将其不停的分为左边和右边两份,#           然后以此递归分下去。然后再将她们按照两个有序数组的样子合并起来。# 举例[4,7,8,3,5,9]# 第一步:分:[4,8,7] [3,9,5] ->[4,8] [7] [3,9] [5] -> [4] [8] [7] [3] [9] [5]# 第二步:并:[4,8] [7] [3,9] [5] ->[4,7,8] [3,5,9] -> [3,4,5,7,8,9]def merge(a,b):#此时a和b都为已经排序好的列表    c = []    h = j = 0    while j<len(a) and h<len(b):#依次比较直到a或b的元素被全部排完        if a[j]<b[h]:            c.append(a[j])            j+=1        else:            c.append(b[h])            h+=1    if j==len(a):        #当a里的元素全部排完了,将b里剩下的元素依次排入c        for i in b[h:]:            c.append(i)    else:        #当b里的元素全部排完了,将a里剩下的元素依次排入c        for i in a[j:]:            c.append(i)    return c#递归法def mergesort(numList):    print(numList)    if len(numList) <= 1:        return numList    middle = len(numList) / 2    left = mergesort(numList[:middle])    right = mergesort(numList[middle:])    return merge(left, right)print(mergesort([1,2,-1,8,6,7,-2]))# [1, 2, -1, 8, 6, 7, -2]# [1, 2, -1]# [1]# [2, -1]# [2]# [-1]# [8, 6, 7, -2]# [8, 6]# [8]# [6]# [7, -2]# [7]# [-2]#遍历法def mergesort1(numList):    lenList = len(numList)    while lenList>1:        newList = []        if lenList % 2 == 0:            for i in range(lenList/2):                a = [numList[2*i]] if type(numList[2*i]) == int else numList[2*i]                b = [numList[2*i+1]] if type(numList[2*i+1]) == int else numList[2*i+1]                newList.append(merge(a, b))            numList = newList            lenList = len(numList)        else:            for i in range(lenList/2):                a = [numList[2 * i]] if type(numList[2*i]) == int else numList[2 * i]                b = [numList[2 * i + 1]] if type(numList[2*i+1]) == int else numList[2 * i + 1]                newList.append(merge(a, b))            last = [numList[-1]] if type(numList[-1]) == int else numList[-1]            newList.append(last)            numList = newList            lenList = len(numList)        print(newList)        print(lenList)    return numList[0]#print(mergesort1([1,2,-1,8,7,6,-2]))print(mergesort1([1,2,-1,8,6,7,-2,-13,58,30,-15,18]))# [[1, 2], [-1, 8], [6, 7], [-2]]# 4# [[-1, 1, 2, 8], [-2, 6, 7]]# 2# [[-2, -1, 1, 2, 6, 7, 8]]# 1# [-2, -1, 1, 2, 6, 7, 8]#希尔排序(在直接插入排序的基础上加上间隔)#基本思想:1.定义步长序列t为[k,...,1]#          2.按照步长序列个数k,对排序队列进行k趟排序#          3.每趟排序,根据对应的步长ti,将待排序列分割成ti个子序列,分别对#            各个子序列进行直接插入排序。def insertsort(numList):    leng = len(numList)    gap = leng    while(gap>1):        gap = gap // 2        print(gap)        for i in range(gap,leng):            if numList[i] < numList[i-gap]:                midnum = numList[i]                j=i-gap                while numList[j] >midnum and j >= 0:                    numList[j+gap] = numList[j]                    j -=gap                numList[j + gap] = midnum            print(numList)    return numListprint(insertsort([1,2,-1,8,6,7,-2,-13]))
[1,2,-1,8,6,7,-2,-13]
# 间隔为4# [1, 2, -1, 8, 6, 7, -2, -13]# [1, 2, -1, 8, 6, 7, -2, -13]# [1, 2, -2, 8, 6, 7, -1, -13]# [1, 2, -2, -13, 6, 7, -1, 8]# 间隔为2# [-2, 2, 1, -13, 6, 7, -1, 8]# [-2, -13, 1, 2, 6, 7, -1, 8]# [-2, -13, 1, 2, 6, 7, -1, 8]# [-2, -13, 1, 2, 6, 7, -1, 8]# [-2, -13, -1, 2, 1, 7, 6, 8]# [-2, -13, -1, 2, 1, 7, 6, 8]# 间隔为1# [-13, -2, -1, 2, 1, 7, 6, 8]# [-13, -2, -1, 2, 1, 7, 6, 8]# [-13, -2, -1, 2, 1, 7, 6, 8]# [-13, -2, -1, 1, 2, 7, 6, 8]# [-13, -2, -1, 1, 2, 7, 6, 8]# [-13, -2, -1, 1, 2, 6, 7, 8]# [-13, -2, -1, 1, 2, 6, 7, 8]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!