【算法】归并排序 详解

这篇具有很好参考价值的文章主要介绍了【算法】归并排序 详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【算法】归并排序 详解,算法,算法,排序算法,java

排序: 排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

稳定性: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中, r[i] = r[j], 且 r[i] 在 r[j] 之前,而在排序后的序列中, r[i] 仍在 r[j] 之前,则称这种排序算法是稳定的;否则称为不稳定的。
(注意稳定排序可以实现为不稳定的形式, 而不稳定的排序实现不了稳定的形式)

【算法】归并排序 详解,算法,算法,排序算法,java

内部排序: 数据元素全部放在内存中的排序。

外部排序: 数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:

  • 分解(Divide):将n个元素分成两个个含n/2个元素的子序列。
  • 解决(Conquer):用合并排序法对两个子序列递归的排序。
  • 合并(Combine):合并两个已排序的子序列已得到排序结果。

【算法】归并排序 详解,算法,算法,排序算法,java

【算法】归并排序 详解,算法,算法,排序算法,java

代码实现

1. 递归版本

	public static void mergeSort(int[] arr) {
        int len = arr.length;
        partition(arr, 0, len-1);
    }


    public static void partition(int[] arr, int left, int right) {
        if (left >= right) {
            return;
        }
        // 将区间分成左右两个部分, 并将两个部分分别排序
        int mid = ((right-left) >> 1) + left;
        partition(arr, left, mid);
        partition(arr, mid+1, right);
        // 将两部分合并
        int[] temp = new int[right-left+1];
        int index = 0;
        int index1 = left;
        int index2 = mid+1;
        while (index1 <= mid && index2 <= right) {
            if (arr[index1] < arr[index2]) {
                temp[index++] = arr[index1++];
            } else {
                temp[index++] = arr[index2++];
            }
        }
        while (index1 <= mid) {
            temp[index++] = arr[index1++];
        }
        while (index2 <= right) {
            temp[index++] = arr[index2++];
        }
        // 重新拷贝回去
        for (int i = 0; i < index; i++) {
            arr[left+i] = temp[i];
        }
    }

2. 非递归版本

    public static void mergeSortNonR(int[] arr) {
        int len = arr.length;
        // i 表示的是, 左右区间中每个区间的元素个数
        for (int i = 1; i < len; i*=2) {
            // j 每次要跳过两个区间
            for (int j = 0; j < len; j += 2*i) {
                int left1 = j;
                int right1 = j + i - 1;
                int left2 = right1 + 1;
                int right2 = left2 + i - 1;
                // 修正一下 right1, right2, 因为可能 right1 和 right2 越界了
                if (right1 >= len) {
                    right1 = len-1;
                }
                if (right2 >= len) {
                    right2 = len - 1;
                }
                // 开始合并
                int[] temp = new int[2*i];
                int index = 0;
                while (left1 <= right1 && left2 <= right2) {
                    if (arr[left1] <= arr[left2]) {
                        temp[index++] = arr[left1++];
                    } else {
                        temp[index++] = arr[left2++];
                    }
                }
                while (left1 <= right1) {
                    temp[index++] = arr[left1++];
                }
                while (left2 <= right2) {
                    temp[index++] = arr[left2++];
                }
                // 拷贝回去
                for (int k = 0; k < index; k++) {
                    arr[j+k] = temp[k];
                }
            }
        }
    }

总结:

  • 时间复杂度: O(N*logN)
  • 空间复杂度: O(N)
  • 是稳定排序
  • 对数据不敏感: 不管数据原本怎么排列, 都需要先分解, 然后归并。
  • 归并的缺点在于需要 O(N) 的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。

海量数据的排序问题
假设条件为:内存只有 1G,需要排序的数据有 100G
因为内存中因为无法把所有数据全部放下,所以需要外部排序,而归并排序是最常用的外部排序

  1. 先把文件切分成 200 份,每个 512 M
  2. 分别对 512 M 排序,因为内存已经可以放的下,所以任意排序方式都可以
  3. 进行 2 路归并,同时对 200 份有序文件做归并过程,最终结果就有序了

以上就是对归并排序的讲解, 希望能帮到你 !
评论区欢迎指正 !
文章来源地址https://www.toymoban.com/news/detail-697817.html

到了这里,关于【算法】归并排序 详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【排序算法】 归并排序详解!深入理解!思想+实现!

    🎥 屿小夏 : 个人主页 🔥个人专栏 : 算法—排序篇 🌄 莫道桑榆晚,为霞尚满天! ​ 什么是归并?通过归并排序就能让数据有序?分治法是怎么在归并排序上应用的?本文将对归并排序进行细致入微的讲解,庖丁解牛般让你彻底明白归并排序! 归并排序(MERGE-SORT)是建

    2024年02月08日
    浏览(44)
  • 【算法】归并排序 详解

    排序: 排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 稳定性: 假定在待排序的记录序列中,存在多个具有相同的的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中, r[i] = r[j], 且 r[i] 在 r[j] 之前,而

    2024年02月09日
    浏览(33)
  • 【排序算法】 归并排序详解!深入理解!思想+源码实现!

    🎥 屿小夏 : 个人主页 🔥个人专栏 : 算法—排序篇 🌄 莫道桑榆晚,为霞尚满天! ​ 什么是归并?通过归并排序就能让数据有序?分治法是怎么在归并排序上应用的?本文将对归并排序进行细致入微的讲解,庖丁解牛般让你彻底明白归并排序! 归并排序(MERGE-SORT)是建

    2024年02月06日
    浏览(46)
  • 算法-归并排序-JAVA

    下面是Java实现归并排序的示例代码: 在归并排序中,首先进行递归地将数组划分为更小的子数组,然后进行合并操作。在合并操作中,将两个有序的子数组合并成一个有序的数组。 上述代码实现了归并排序的主要逻辑。 mergeSort 方法用于调用归并排序的入口,它接受待排序

    2024年02月15日
    浏览(46)
  • 归并排序算法(Java实现)

    也称 合并排序算法 ,是将两个或两个以上的有序数据序列合并成一个新的有序数据序列。该算法采用分治法(Divide and Conquer)的思想,将待排序的序列分成若干个子序列,分别对子序列进行排序,然后将有序的子序列合并成一个大的有序序列 注:将几个有序队列合并成一个

    2024年01月17日
    浏览(38)
  • Java 语言实现归并排序算法

    【引言】 归并排序算法是一种高效且稳定的排序算法。它采用分治法的思想,将数组反复分割成两个子数组,直到每个子数组只有一个元素。然后将这些子数组逐个合并,最终得到排序完毕的数组。本文将使用Java语言实现归并排序算法,并详细讲解其核心思想和代码实现。

    2024年02月11日
    浏览(35)
  • [排序算法]:归并排序(Merge Sort)(递归与非递归实现详解)

            归并排序,是创建在归并操作上的一种有效的排序算法。算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。归并排序思路简单,速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。

    2024年01月20日
    浏览(45)
  • 详解八大排序算法-附动图和源码(插入,希尔,选择,堆排序,冒泡,快速,归并,计数)

    目录 🍏一.排序的概念及应用🍏  1.排序的概念  2.排序的应用  3.常用的排序算法 🍎二.排序算法的实现🍎 1.插入排序 1.1直接插入排序 1.2希尔排序(缩小增量排序) 2.选择排序 2.1直接选择排序 2.2堆排序 3.比较排序 3.1冒泡排序 3.2快速排序  递归版本 快速排序递归优化 快速

    2024年02月01日
    浏览(65)
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序,堆排序】超详细~~

    目录 冒泡排序(BubbleSort): 代码详解:  冒泡排序的优化:  选择排序(SelectSort): 代码详解:  插入排序(InsertSort): 代码详解:  希尔排序(ShellSort):  法一(交换法)代码详解:  法二(移位法--插入排序的优化)代码详解: 快速排序(QuickSort):  代码详解:  归并排

    2024年02月20日
    浏览(48)
  • 七大排序算法——归并排序,通俗易懂的思路讲解与图解(完整Java代码)

    排序:所谓排序,就是使一串记录,按照其中的某个或某些的大小,递增或递减的排列起来的操作。 上述待排序的数中,有两个5。 将 前面 的5标记一个a, 将 后面 的5标记一个b。 通过算法进行排序后,这一组数就有序了, 但是要看两个相同的5的位置是否有改变。

    2024年02月15日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包