• 数据结构与算法:归并排序(原理讲解+python实现)


    归并排序

    归并排序是一种常见并且广泛运用的排序算法。由于其采用了二叉树层级的理念从而降低时间复杂度 充分提升了性能。常见的我们会运用递归来写归并排序的代码 其实通过迭代的方式来实现归并排序不失为一种好的方式。

    原理讲解

    归并排序基于分治策略(Divide and Conquer Stretegy)实现。分:先将要排序长度为n的列表或者数组折中分成两个子列表或者数组长度分别为(n/2) 第二次则分别将子序列分成总共4个子序列 每个子序列长度为(n/4) 以此继续分下去,直到子序列只剩下1个元素不能再分而停止。治:将最后分成的n个元素开始逐级合并,第一层治策略是将分策略最后一层得到的元素根据分策略逐个“修补”起来,俗话说就是分策略的逆过程。如图所示:

    Python实现

     1 def mergeSort(a, l, r):
     2     tmp = [0 for _ in range(len(a))]  # 开辟一个与列表a相同长度的临时列表空间
     3     sort(a, l, r, tmp)
     4 
     5 def sort(a, l, r, tmp):
     6     if l < r:
     7         mid = (l + r)//2
     8         sort(a, l, mid, tmp)  # 左边归并排序 使左边子序列有序
     9         sort(a, mid+1, r, tmp)  # 右边归并排序 使右边子序列有序
    10         merge(a, l, mid, r, tmp)  # 将左右两个有序的子序列合并操作
    11 
    12 def merge(a, l, mid, r, tmp):
    13     t = 0
    14     i = l
    15     j = mid+1
    16     while i <= mid and j <= r:
    17         if a[i] <= a[j]:
    18             tmp[t] = a[i]; t+=1; i+=1
    19         else:
    20             tmp[t] = a[j]; t+=1; j+=1
    21 
    22     while i <= mid:  # 右子序列比较完没有元素后 将左子序列剩下的添加临时列表后面
    23         tmp[t] = a[i]; t+=1; i+=1
    24 
    25     while j <= r:  # 左子序列比较完没有元素后 将右子序列剩下的添加临时列表后面
    26         tmp[t] = a[j]; t+=1; j+=1
    27 
    28     t = 0
    29     while l <= r:  # 将临时列表中的数复制到原来数组当中
    30         a[l] = tmp[t]; l+=1; t+=1
    31 
    32 if __name__ == '__main__':
    33     a = [4, 2, 7, 8, 1, 3, 5, 6]
    34     r = len(a)-1
    35     l = 0
    36     mergeSort(a, l, r)
    37     print(a)

    时间、空间复杂度 稳定性分析

    时间复杂度:归并排序由于运用了二叉树的策略所以在分策略上是logn的时间复杂度,治策略每一层都必须比较所以n个元素, 总共有n层所以最后的时间复杂度是O(nlogn)。它不受待排序列表完全逆序的影响所以平均时间复杂度是O(nlogn)。

    空间复杂度:过程开辟了长度为n的临时空间 所以空间复杂度是O(n)

    稳定性分析:当左右子序列比较的两个元素相等时,左子序列的相同元素为先加入到临时序列中 所以相同元素的顺序在排序之后未发生改变 ,归并排序是稳定性排序。

    总结

    各种排序算法都有其自身的不可替代性,在实际运用的过程中,特别是数量巨大时,一定要结合数据的性质本身和排序算法本身来决定要用何种算法。

  • 相关阅读:
    [数据结构与算法 01] 什么是数据结构?什么是算法?联系是什么?常用的数据结构/算法有?
    程序员面试金典-面试题 16.05. 阶乘尾数
    程序员面试金典-面试题 16.04. 井字游戏
    程序员面试金典-面试题 16.02. 单词频率
    程序员面试金典-面试题 16.01. 交换数字
    程序员面试金典-面试题 10.11. 峰与谷
    程序员面试金典-面试题 10.10. 数字流的秩
    程序员面试金典-面试题 10.09. 排序矩阵查找
    程序员面试金典-面试题 10.05. 稀疏数组搜索
    程序员面试金典-面试题 10.03. 搜索旋转数组
  • 原文地址:https://www.cnblogs.com/confessionlouis/p/14344059.html
Copyright © 2020-2023  润新知