【算法系列 | 4】深入解析排序算法之——归并排序

02-29 阅读 0评论

【算法系列 | 4】深入解析排序算法之——归并排序

序言

你只管努力,其他交给时间,时间会证明一切。

【算法系列 | 4】深入解析排序算法之——归并排序,【算法系列 | 4】深入解析排序算法之——归并排序,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,前端,第2张
(图片来源网络,侵删)

文章标记颜色说明:

  • 黄色:重要标题
  • 红色:用来标记结论
  • 绿色:用来标记一级论点
  • 蓝色:用来标记二级论点

    决定开一个算法专栏,希望能帮助大家很好的了解算法。主要深入解析每个算法,从概念到示例。

    我们一起努力,成为更好的自己!

    今天第3讲,讲一下排序算法的归并排序(Merge Sort)

    1 基础介绍

    排序算法是很常见的一类问题,主要是将一组数据按照某种规则进行排序。

    以下是一些常见的排序算法:

    【算法系列 | 4】深入解析排序算法之——归并排序,【算法系列 | 4】深入解析排序算法之——归并排序,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,前端,第3张
    (图片来源网络,侵删)
    1. 冒泡排序(Bubble Sort)

    2. 插入排序(Insertion Sort)

    3. 选择排序(Selection Sort)

    4. 归并排序(Merge Sort)

    5. 快速排序(Quick Sort)

    6. 堆排序(Heap Sort)

      【算法系列 | 4】深入解析排序算法之——归并排序,【算法系列 | 4】深入解析排序算法之——归并排序,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,前端,第4张
      (图片来源网络,侵删)

    一、基本介绍介绍

    1.1 原理介绍

    归并排序(Merge Sort)是一种基于分治思想的排序算法,它将待排序的数组分成两部分,分别对这两部分递归地进行排序,最后将两个有序子数组合并成一个有序数组。它的时间复杂度为 O(nlogn)。

    归并排序的基本思路是将待排序的数组分成两个部分,分别对这两部分进行排序,然后将排好序的两部分合并成一个有序数组。这个过程可以用递归来实现。具体的实现步骤如下:

    1. 分解:将待排序的数组不断分成两个子数组,直到每个子数组只有一个元素为止。

    2. 合并:将相邻的两个子数组合并成一个有序数组,直到最后只剩下一个有序数组为止。

    合并的过程中,需要用到一个辅助数组来暂存合并后的有序数组。具体来说,假设待合并的两个有序数组分别为 A 和 B,它们的长度分别为 n 和 m,合并后的有序数组为 C,那么合并的过程可以按如下步骤进行:

    1. 定义三个指针 i、j 和 k,分别指向数组 A、B 和 C 的起始位置。

    2. 比较 A[i] 和 B[j] 的大小,将小的元素放入 C[k] 中,并将对应指针向后移动一位。

    3. 重复步骤 2,直到其中一个数组的元素全部放入 C 中。

    4. 将另一个数组中剩余的元素放入 C 中。

    归并排序的优点是稳定性好,即对于相等的元素,在排序前后它们的相对位置不会改变。缺点是需要额外的空间来存储辅助数组。

    原理简单示例 

    以下是一个示例,演示了如何使用归并排序对一个数组进行排序:

    假设要对数组 [5, 2, 4, 6, 1, 3] 进行排序。

    1. 首先将数组分成两部分:[5, 2, 4] 和 [6, 1, 3]。

    2. 对左右两部分分别递归调用归并排序。对于左半部分,继续进行分解,将其分成两部分:[5] 和 [2, 4]。对于右半部分,也进行相同的操作,将其分成两部分:[6] 和 [1, 3]。

      对于 [5] 和 [2, 4],由于它们的长度都小于等于 1,因此直接返回它们本身。对于 [6] 和 [1, 3],同样返回它们本身。

    3. 接下来将排好序的左右两部分合并成一个有序数组。对于左半部分,由于它只有一个元素,因此可以直接将其作为有序数组。对于右半部分,需要将 [1, 3] 进行排序,排序后得到 [1, 3, 6]。

    4. 将排好序的左右两部分合并成一个有序数组。对于左半部分,指针 i 指向其起始位置,即 0;对于右半部分,指针 j 指向其起始位置,即 0。比较左右两部分的元素大小,发现左半部分的第一个元素 5 大于右半部分的第一个元素 1,因此将 1 添加到新的数组 sorted_arr 中,并将右半部分的指针 j 向后移动一位。此时,sorted_arr 的内容为 [1]。接着比较左半部分的第二个元素 2 和右半部分的第一个元素 3,发现左半部分的元素较小,因此将 2 添加到 sorted_arr 中,并将左半部分的指针 i 向后移动一位。此时,sorted_arr 的内容为 [1, 2]。接着继续比较左右两部分的元素大小,将它们依次添加到 sorted_arr 中。最终得到排好序的数组 [1, 2, 3, 5, 6]。

    因此,对于输入的数组 [5, 2, 4, 6, 1, 3],使用归并排序后得到的排好序的数组为 [1, 2, 3, 4, 5, 6]。

    1.2 复杂度 

    归并排序的时间复杂度为 O(nlogn),其中 n 是待排序数组的长度。

    这个复杂度可以通过分治的思想来解释。

    首先将待排序的数组分成两部分,对每一部分递归调用归并排序,然后将两部分合并成一个有序数组。

    每次递归调用都将数组的长度减半,因此需要进行 logn 次递归调用。在每个递归层次中,需要将两个有序数组合并成一个有序数组,这一过程需要线性时间 O(n)。因此,归并排序的总时间复杂度为 O(nlogn)。

    归并排序的空间复杂度为 O(n),其中 n 是待排序数组的长度。在排序过程中,需要使用一个辅助数组来存储合并后的有序数组。

    这个辅助数组的长度等于待排序数组的长度,因此归并排序的空间复杂度为 O(n)。如果实现中使用链表来存储数据,空间复杂度可以降低为 O(1)。

    1.3使用场景

    归并排序的应用场景比较广泛,主要适用于以下几种情况:

    1. 对于大规模的数据排序:归并排序的时间复杂度为 O(nlogn),相比于其他排序算法如冒泡排序、插入排序等,它在处理大规模数据时更加高效。

    2. 对于稳定排序的需求:归并排序是一种稳定排序算法,即对于相等的元素,在排序前后它们的相对位置不会改变。

    3. 对于需要保证排序稳定性的需求:归并排序是一种基于比较的排序算法,不依赖于数据的初始状态,具有较好的稳定性。

    4. 对于需要多路排序的需求:归并排序可以轻松地扩展到多路排序,即将待排序的数组分成多个子数组,对每个子数组分别进行归并排序,然后将它们合并成一个有序数组。

    5. 对于需要外部排序的需求:归并排序可以应用于外部排序,即在排序过程中将数据存储在外部存储器中,而不是在内存中。在外部排序中,需要使用多路归并排序来合并不同的子文件。

    总的来说,归并排序是一种高效、稳定的排序算法,适用于大规模数据的排序、需要保证排序稳定性的需求以及外部排序等场景。

    二、代码实现

    2.1 Python 实现

    以下是使用 Python 实现归并排序的完整代码:

    def merge_sort(arr):
        if len(arr) 

免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,人围观)

还没有评论,来说两句吧...

目录[+]