zoukankan      html  css  js  c++  java
  • 排序算法(归并排序法待补充)

    要点概论:

    1. 冒泡排序法

    2. 选择排序法

    3. 插入排序法

    4. 快速排序法

    5. 归并排序法

    6. python 语言提供的排序算法

    1. 冒泡排序法

      冒泡排序法时最简单的排序算法。对于包含 N 个元素的列表 A ,按递增顺序排列的冒泡法的算法如下。

      

      1)第一轮比较:从第一个元素开始,对列表中所有 N 个元素进行两两大小比较,如果不满足升序关系,则交换。

        即 A[0] 与 A[1] 比较,若A[0] > A[1] , 则 A[0] 与 A[1] 交换;然后 A[1] 与 A[2] 比较,若A[1] > A[2] ,则 A[1]  与  A[2] 交换; 

        ......直至最后 A[N -2] 与 A[N - 1] 比较, 若 A[N - 2] > A[N -1] ,则 A[N -2] 与 A[N - 1] 交换。

        第一轮比较完成后,列表元素中最大的数 “沉” 到列表最后,而那些较小的数如同气泡一样上浮一个位置,顾名思义 “冒泡法” 排序

      2)第二轮比较:从第一个元素开始,对列表中前 N - 1 个元素(第 N 个元素,即 A[N - 1]已经最大,无须参加排序)继续两两大小比较,如果不满足升序关系,则交换。

        第二轮比较完成后,列表元素中次大的数 “沉” 到最后,即 A[N - 2] 为列表元素中次大的数。

      3)以此类推,进行第 N - 1 轮比较后,列表中所有元素均按递增顺序排好序。

      PS:若要按递减顺序对列表排序,则每次两两大小比较时,如果不满足降序关系,则交换即可。

      冒泡排序法的过程如下表所示:

    原始列表 2 97 86 64 50 80 3 71 8 76
    第一轮比较 2 86 64 50 80 3 71 8 76 97
    第二轮比较 2 64 50 80 3 71 8 76 86 97
    第三轮比较 2 50 64 3 71 8 76 80 86 97
    第四轮比较 2 50 3 64 8 71 76 80 86 97
    第五轮比较 2 3 50 8 64 71 76 80 86 97
    第六轮比较 2 3 8 50 64 71 76 80 86 97
    第七轮比较 2 3 8 50 64 71 76 80 86 97
    第八轮比较 2 3 8 50 64 71 76 80 86 97
    第九轮比较 2 3 8 50 64 71 76 80 86 97

     

      冒泡排序算法的主要时间消耗时比较次数。

      当  i = 1 时,比较次数为 N - 1;当 i = 2 时,比较次数为 N - 2;依次类推。总共比较次数为:(N -1)+(N - 2)+ ...... + 2 + 1 = N(N -1)/ 2。

      故冒泡排序法的时间复杂度为 O(N²).

      

      冒泡排序算法的实现(bubbleSort.py):

    def bubbleSort(a):
        for i in range(len(a)-1,-1,-1):     # 外循环
            for j in range(i):                     # 内循环
                if a[j] > a[j + 1]:                # 大数往下沉
                    a[j],a[j + 1] = a[j + 1],a[j]
            # print(a)      # 跟踪调试
    
    def main():
        a = [2,97,86,64,50,80,3,71,8,76]
        bubbleSort(a)
        print(a)
    
    if __name__ == '__main__':
        main()
    
    # 程序运行结果如下:
    # [2, 3, 8, 50, 64, 71, 76, 80, 86, 97]   
    bubbleSort.py

      

    2. 选择排序法

      对于包含 N 个元素的列表 A ,按递增顺序排序的选择法的基本思想是:每次在若干无序数据中查找最小数,并放在无序数据中的首位。其算法如下:

      

      1)从 N 个元素的列表中找最小值及其下标,最小值与列表的第一个元素交换。

      2)从列表的第二个元素开始的 N - 1 个元素中再找最小值及其下标,该最小值(即整个列表元素的次小值)与列表第二个元素交换。

      3)以此类推,进行第 N - 1 轮选择和交换后,列表中所有元素均按递增顺序排好序。

      PS:若要按递减顺序对列表排序,只要每次查找并交换最大值即可。

      选择排序法的过程如下表所示:

    原始数组 59 12 77 64 72 69 46 89 31 9
    第一轮比较 9 12 77 64 72 69 46 89 31 59
    第二轮比较 9 12 77 64 72 69 46 89 31 59
    第三轮比较 9 12 31 64 72 69 46 89 77 59
    第四轮比较 9 12 31 46 72 69 64 89 77 59
    第五轮比较 9 12 31 46 59 69 64 89 77 72
    第六轮比较 9 12 31 46 59 64 69 89 77 72
    第七轮比较 9 12 31 46 59 64 69 89 77 72
    第八轮比较 9 12 31 46 59 64 69 72 77 89
    第九轮比较 9 12 31 46 59 64 69 72 77 89

      

      选择排序算法的主要时间消耗时比较次数。

      当 i = 1时,比较次数时 N - 1;当 i = 2 时,比较次数为 N - 2;以此类推。总共比较次数为:(N - 1)+(N - 2)+ ...... + 2 + 1 = N(N - 1)/ 2。

      故选择排序算法的时间复杂度为 O(N²)。

      选择排序算法的实现:

    def selectionSort(a):
        for i in range(0,len(a)):            # 外循环 (0 ~ N-1)
            m = i                            # 当前位置下标
            for j in range(i+1,len(a)):     # 内循环
                if a[j] < a[m]:             # 查找最小值的位置
                    m = j                   
            a[i],a[m] = a[m],a[i]           #元素交换
            # print(a)      # 跟踪调试
    
    def main():
        a = [59,12,77,64,72,69,46,89,31,9]
        selectionSort(a)
        print(a)
        
    if __name__ == '__main__':
        main()
    
    # 程序运行结果如下:
    # [9, 12, 31, 46, 59, 64, 69, 72, 77, 89]
    selectionSort.py

    3. 插入排序法

      对于包含 N 个元素的列表 A ,按递增顺序排序的插入排序法的基本思想是:依次检查列表中的每个元素,将其插入到其左侧已经排好序的列表中的适当位置。其算法如下:

      

      1)第二个元素与列表中其左侧的第一个元素比较,如果 A[0] > A[1] ,则交换位置,结果左侧两个元素排序完毕。

      2)第三个元素依次与其左侧的列表的元素比较,直至插入对应的排序位置,结果左侧的三个元素排序完毕。

      3)依次类推,进行第 N-1 轮比较和交换后,列表中所有元素均按递增顺序排好序。

      PS:若要按递减顺序对列表排序,只要每次查找并交换最大值即可。

      插入排序法的过程如下表所示:

    原始数组 59 12 77 64 72 69 46 89 31 9
    第一轮比较 12 59 77 64 72 69 46 89 31 9
    第二轮比较 12 59 77 64 72 69 46 89 31 9
    第三轮比较 12 59 64 77 72 69 46 89 31 9
    第四轮比较 12 59 64 72 72 69 46 89 31 9
    第五轮比较 12 59 64 69 72 77 46 89 31 9
    第六轮比较 12 46 59 64 69 72 77 89 31 9
    第七轮比较 12 46 59 64 69 72 77 89 31 9
    第八轮比较 12 31 46 59 64 69 72 77 89 9
    第九轮比较 9 12 31 46 59 64 69 72 77 89

      在最理想的情况下(列表处于排序状态),while 循环仅需要一次比较,故总的运行时间为线性;

      在最差的情况下(列表为逆序状态),此时内循环指令执行次数为: 1 + 2 + ...... +N - 1 = N(N - 1)/ 2 。

      故插入排序算法的时间复杂度为 O(N²) 。

       插入排序算法的实现(insertSort.py)。

    def insertSort(a):
        for i in range(1,len(a)):                   # 外循环 (1 ~ N-1)
            j = i
            print(j)
            # time.sleep(1)
            while (j > 0) and (a[j] < a[j - 1]):   # 内循环
                a[j],a[j - 1] = a[j - 1],a[j]       # 元素交换
                j -= 1                              # 继续循环
                print(j)
            # print(a)      跟踪调试
    
    def main():
        a = [59,12,77,64,72,69,46,89,31,9]
        insertSort(a)
        print(a)
    
    if __name__ == '__main__':
        main()
    
    # 程序运行结果如下:
    # [9, 12, 31, 46, 59, 64, 69, 72, 77, 89]
    insertSort.py

    4. 快速排序法

      快速排序法是对冒泡排序的一种改进,其基本思想是:

      通关过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据要小;然后递归对这两部分数据分别进行快速排序。

      

      快速排序算法的一趟排序和操作步骤如下:

      1)设置两个变量 i 和 j ,分别为列表首末元素的下标,即  i = 0 ,j = N - 1。

      2)设置列表的第一个元素作为关键数据,即 key = A[0]。

      3)从 j 开始向前搜索,找到第一个小于 key 的值 A[ j ] ,将 A[ j ] 和 A[ i ] 互换。

      4)从 i  开始向后搜索,找到第一个大于 key 的值 A[ i ] ,将 A[ i ] 和 A[ j ] 互换。

      5)重复第(3)和(4)步,直到 i = j 。

      快速排序的一趟排序的算法如下表所示:

    下标 0 1 2 3 4 5 6 7 8 9
    原始数组 59 12 77 64 72 69 46 89 31 9
    第一轮比较交换 9 12 77 64 72 69 46 89 31 59
    第二轮比较交换 9 12 59 64 72 69 46 89 31 77
    第三轮比较交换 9 12 31 64 72 69 46 89 59 77
    第四轮比较交换 9 12 31 59 72 69 46 89 64 77
    第五轮比较交换 9 12 31 46 72 69 59 89 64 77
    第六轮比较交换 9 12 31 46 59 69 72 89 64 77
    第七轮比较交换 9 12 31 46 59 69 72 89 64 77

      快速排序最坏情况下,每次划分选取的基准都是当前无序列表中关键字最小(或最大)的记录,时间复杂度为 O(N²)

      平均情况下,其时间复杂度为 O(Nlog2N)

      快速排序算法的实现(quickSort.py)。

    def quickSort(a,low,high):      # 对列表 a 快速排序,下界为 low ,上界为 high
        i = low                     # i 等于列表下界
        j = high                    # j 等于列表上界
        if i >= j:                  # 如果下界大于等于上界,法妞结果列表 a
            return a
        key = a[i]                  # 设置列表的第一个元素作为关键数据
        # print(key)        # 跟踪调试
        while i < j:        # 循环直到 i = j
            while i < j and a[j] >= key:    # j 开始向前搜索,找到第一个小于 key 的值 a[j]
                j = j - 1
            a[i] = a[j]
            while i < j and a[i] <= key:    # i 开始向后搜索,找到第一个大于 key 的 a[i]
                i = i + 1
            a[j] = a[i]
        a[i] = key                  # a[i] 等于关键数据
        # print(a)      # 跟踪调试
        quickSort(a,low,i - 1)      # 递归调用快速排序算法(列表下界为 low ,上界为 i - 1 )
        quickSort(a,j + 1,high)     # 递归调用快速排序算法(列表下界为 j + 1 ,上界为 high)
    
    def main():
        a = [59,12,77,64,72,69,46,89,31,9]
        quickSort(a,0,len(a) - 1)
        print(a)
    
    if __name__ == '__main__':
        main()
    
    # 程序运行结果如下
    # [9,12,31,46,59,64,69,72,77,89]
    quickSort.py

    5. 归并排序法(待补充)

    6. python 语言提供的排序算法

      python 语言提供了下列排序算法:

      1)内置数据类型 list 中的方法 sort() ,把列表的项按升序重新排列。

      2)内置函数 sorted() 则保持原列表不变,函数返回一个新的包含按升序排列的项的列表。

      python 系统排序方法使用了一种归并排序算法的版本,但使用了 python 无法编写的底层实现,从而避免了 python 本身附加的大量开销,故其速度比 mergeSort.py 快很多(10 ~ 20倍)。

      系统排序方法同样用于任何可比较的数据类型,例如,python 内置的 str ,int 和 float 数据类型,

      

      

  • 相关阅读:
    js图片加载效果(延迟加载+瀑布流加载)
    iOS仿支付宝芝麻信用仪表盘效果
    Spark GraphX 的数据可视化
    [Animations] 快速上手 iOS10 属性动画
    iOS蓝牙BLE4.0通信功能
    微信小程序项目实战之天气预报
    Android利用温度传感器实现带动画效果的电子温度计
    Eclipse集成ijkplayer并实现本地和网络视频播放等
    Android HandlerThread详解
    AsyncTask 异步任务基本使用-下载视频
  • 原文地址:https://www.cnblogs.com/HZY258/p/8469454.html
Copyright © 2011-2022 走看看