zoukankan      html  css  js  c++  java
  • Python经典排序算法

    https://www.cnblogs.com/onepixel/p/7674659.html这个文章很nice

    https://www.bilibili.com/video/av685670?from=search&seid=1637373535603658338这个动图优秀

    https://www.icourse163.org/course/ZJU-93001   MOOC浙大 数据结构 陈越、何钦铭

    VisuAlgo - visualising data structures and algorithms through animation    数据结构与算法的可视化网站  更容易让人感性理解各种算法


    冒泡排序、选择排序、插入排序这三个是最慢也是最经典的三个排序算法

    快速排序对于大的乱数串列一般相信是最快的已知排序

    冒泡排序 bubble sort

    最简单的排序算法,也是效率最差的,因为它必须在最终位置知道前交换,浪费许多“交换操作”

    如果列表已经排序,则是最好情况,遍历期间无需交换,如果发现已经排序,可以提前终止,这种修改下的冒泡通常称为短冒泡排序


    时间复杂度: 平均O(n^2)    最差O(n^2)     最好O(n)

    空间复杂度:O(1)

    稳定

    #测试输入数组
    alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
    
    #冒泡排序
    for i in range(len(alist)-1):
        for j in range(len(alist)-1-i):
            if alist[j] > alist[j+1]:
                alist[j],alist[j+1] = alist[j+1],alist[j]
            
    #排序结果输出
    print('sorted:',alist)

    选择排序 selection sort

    选择排序改进了冒泡排序,每次遍历列表只做一次交换


    时间复杂度:平均O(n^2)    最差O(n^2)    最好O(n^2)

    空间复杂度:O(1)

    不稳定

    #测试输入数组
    alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
    
    #选择排序
    for i in range(len(alist)-1):
        least = i
        for j in range(i+1,len(alist)):
            if alist[j] < alist[least]:
                least = j
        if least != i:
            alist[least],alist[i] = alist[i],alist[least]
    
    #排序结果输出
    print('sorted:',alist)
    

    插入排序 insertion sort

    它始终在列表的较低位置维护一个排序的子列表,然后将每个新项 “插入” 回先前的子列表,使得排序的子列表成为较大的一个项


    时间复杂度: 平均O(n^2)    最差O(n^2)     最好O(n)

    空间复杂度:O(1)

    稳定

    #测试输入数组
    alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
    
    #插入排序
    for i in range(1,len(alist)):
        j = i;
        while j>0 and alist[j-1]>alist[j]:
            alist[j-1],alist[j] = alist[j],alist[j-1]
            j -= 1
            
    #排序结果输出
    print('sorted:',alist)
    

    希尔排序 shell sort

    是1959年Shell发明,第一个突破O(n^2)的排序,是对简单插入排序的改进,与插入排序不同的是它优先比较距离较远的元素,又叫“递减增量排序”

    是针对插入排序以下2特点改进:在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;一般来说是低效的,因为插入排序每次只能将数据移动一位

    希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步

    gap概念,gap递减,最后一步就是插入排序,但是此时几乎已经排好序了

    gap是希尔排序核心

    出名的gap设置Marcin Ciura's gap sequence ,gaps = [701, 301, 132, 57, 23, 10, 4, 1],不过下面例子用数组长度不断整除2得到的序列作为gaps


    时间复杂度:平均O(n(logn)^2)    最差O(n^2)    最好O(n)

    空间复杂度:O(1)

    不稳定

    #测试输入数组
    alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
    
    #希尔排序
    gap = len(alist)//2
    while gap>0:
        #对每个gap做插入排序
        for i in range(gap,len(alist)):
            j = i
            while j>=gap and alist[j-gap]>alist[j]:
                alist[j-gap],alist[j] = alist[j],alist[j-gap]
                j -= gap           
        gap = gap//2
    
    #排序结果输出
    print('sorted:',alist)
    

    归并排序 merge sort

    分而治之的策略来提高性能,是分治法的典型应用

    归并排序是一种递归算法,不断将列表拆分为一半

    二路归并 多路归并

    缺点是在合并过程需要额外存储空间


    时间复杂度: 平均O(nlogn)    最差O(nlogn)      最好O(nlogn)

    空间复杂度:O(n)

    稳定

    #测试输入数组
    alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
    
    #归并排序
    def merge_sort(ilist):   
        def merge(left, right):
            result = []
            while left and right:
                result.append((left if left[0] <= right[0] else right).pop(0))
            return result + left + right
        
        if len(ilist) <= 1:
            return ilist
        mid = len(ilist) // 2
        return merge(merge_sort(ilist[:mid]), merge_sort(ilist[mid:]))
    
    #排序结果输出
    print('sorted:',merge_sort(alist))
    

    快速排序 quick sort

    与归并排序相同,采用分治法,而不使用额外存储

    是对冒泡排序的改进

    通常明显比其他算法更快,因为它的内部循环可以在大部分的架构上很有效的达成

    简单的版本和归并排序一样不好,需要额外存储空间,但是可以改为in-place版本,也就不要额外空间了


    时间复杂度: 平均O(nlogn)    最差O(n^2)      最好O(nlogn)

    空间复杂度:O(nlogn)

    不稳定

    #测试输入数组
    alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
    
    #快速排序
    def quick_sort(ilist): 
        length = len(ilist)
        if length <= 1:
            return ilist
        else:
            # Use the last element as the first pivot
            pivot = ilist.pop()
            # Put elements greater than pivot in greater list
            # Put elements lesser than pivot in lesser list
            greater, lesser = [], []
            for element in ilist:
                if element > pivot:
                    greater.append(element)
                else:
                    lesser.append(element)
            return quick_sort(lesser) + [pivot] + quick_sort(greater)
    
    #排序结果输出
    print('sorted:',quick_sort(alist))
    

    堆排序 heap sort

    是对选择排序的一种改进

    利用堆这种数据结构所设计的算法 近似完全二叉树

    堆通常通过一维数组实  大根堆  小根堆


    时间复杂度:平均O(nlogn)    最差O(nlogn)      最好O(nlogn)

    空间复杂度:O(1)

    不稳定

    #测试输入数组
    alist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14]
    
    #堆排序
    def heapify(unsorted, index, heap_size):
        largest = index
        left_index = 2 * index + 1
        right_index = 2 * index + 2
        if left_index < heap_size and unsorted[left_index] > unsorted[largest]:
            largest = left_index
    
        if right_index < heap_size and unsorted[right_index] > unsorted[largest]:
            largest = right_index
    
        if largest != index:
            unsorted[largest], unsorted[index] = unsorted[index], unsorted[largest]
            heapify(unsorted, largest, heap_size)
            
    def heap_sort(unsorted):
        n = len(unsorted)
        for i in range(n // 2 - 1, -1, -1):
            heapify(unsorted, i, n)
        for i in range(n - 1, 0, -1):
            unsorted[0], unsorted[i] = unsorted[i], unsorted[0]
            heapify(unsorted, 0, i)
        return unsorted
    
    #排序结果输出
    print('sorted:',heap_sort(alist))
    
  • 相关阅读:
    第11组(73) 需求分析报告
    第11组(73)团队展示
    结对编程作业
    第02组 Alpha冲刺 总结
    第02组 Alpha冲刺 (6/6)
    第02组 Alpha冲刺 (5/6)
    第02组 Alpha冲刺 (4/6)
    第02组 Alpha冲刺 (3/6)
    第02组 Alpha冲刺 (2/6)
    第02组 Alpha冲刺 (1/6)
  • 原文地址:https://www.cnblogs.com/yongestcat/p/12073317.html
Copyright © 2011-2022 走看看