【归并排序回顾】深入理解归并排序

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


归并排序

一般用在数据量很大的外部排序(放到磁盘上的,内存放不下)
在这里插入图片描述


分治思想:分而治之

归并排序:先划分成(/2,向下取整,把mid也划分到左边)直到都只有单独的一个元素,再合并的过程就是排序的过程。

合并排序,哪一个更小就放在前面,怎么拆分的就怎么合并回去,比较要合并的数组的最前面的元素大小就行,因为他俩是排好序的(升序),选出去的较小就不用管了,接着比较两个数组中剩余的元素的各自第一个元素的大小。

将两个有序表合并成一个称为二路归并

下面那些合并排序的数组都要存到临时数组中,再放回到原来的数组中

比如9、5排成5、9了,原来划分的95来源于952那么就合并回去,那95这个子数组的第一个元素和2这个数组的第一个元素比较,谁小就放前面;把第一次合并的数组(此时仍然是被划分的)再合并
在这里插入图片描述
在这里插入图片描述


划分时怎么知道划分成为一个一个的呢

分治:采用递归,最后left和right相遇了即相等时就意味着只剩一个了。

首先要有个mid,分而治之左边和右边
在这里插入图片描述
在这里插入图片描述


merge 合并并且排序,谁小把谁拉下来

1、比较两个归并数组的第一个元素,第一个数组的开始位置是s1=left,第二个数组的是s2=mid+1,而临时数组temp的长度就是int[r-l+1] 3-0+1;

2、如比较大小后,拉下来一个元素,temp的下标就i++,同时s2++,同理i++,s1++;加入s2++后大于了right,那就要退出循环了,此时还应该判断左边还有没有元素即判断s1还是不是小于mid,小于那就还有,直接拷贝剩下元素进temp数组;同理万一右边数组还有元素呢,同理操作。

在这里插入图片描述


复杂度与稳定性:

时间复杂度:由于是均匀分割的和快排用的基准数那种没关系,所以归并排序最好最坏都是O(nlogn)

空间复杂度:O(n)

归并排序是稳定的排序稳定性:其实这个概念就是说,如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。

在这里插入图片描述

注意:

任何一个稳定的排序都可以实现为不稳定的排序,但是如果它本身就是一个不稳定的排序,那么它就不可能实现为一个稳定排序。

为什么添加一个等号就是稳定的排序?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


常用排序算法复杂度对比:

img


代码实现:

搞懂原理,一步一步写就行。

public static void mergeSort(int[] arr, int left, int right) {
    if (left >= right){     // 递归出口,当left和right相等时跳出
        return;
    }

    int mid = (right + left) >>> 1;     // 无符号右移一位 / 2
    mergeSort(arr, left, mid);
    mergeSort(arr, mid + 1, right);
    merge(arr, left, mid, right);   // 合并
}

private static void merge(int[] arr, int left, int mid, int right) {
    int l1 = left;
    int r1 = mid + 1;
    int[] temp = new int[right - left + 1];
    int i = 0;  // i表示temp数组的下标

    while (l1 <= mid && r1 <= right) {
        if (arr[l1] <= arr[r1]){
            temp[i++] = arr[l1++];
        }else {
            temp[i++] = arr[r1++];
        }
    }

    while (l1 <= mid){
        temp[i++] = arr[l1++];
    }
    while (r1 <= right){
        temp[i++] = arr[r1++];
    }

    for (int j = 0; j < temp.length; j++){
        arr[j + left] = temp[j];
    }
}

参考了很多老师们的讲解,感谢知识共享的年代~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值