归并排序

基本思想

使用了分支的思想,用到了递归,有点像二分法的感觉,中间分开,左半边递归分开,右半边递归分开,直到分到最小,然后再排序组合
直接看图说话吧,还是尚学堂的图,有一说一他们课件真挺好的
在这里插入图片描述

疑惑

我并不觉得这种排序算法会好到哪里,他尽管把左右部分排好序了,但最后还是要再排一遍啊,比如这里
在这里插入图片描述
其实我不太明白这里
所以一会复习关键关注合治
而他的时间复杂度确实是O(nlogn)比插入,冒泡,希尔都要好

代码实现

public class MergeSort {
    public static void main(String[] args) {
        int[] arr = {8,4,5,7,1,3,6,2};
        int[] temp = new int[arr.length];//归并排序需要一个额外空间
        System.out.println("排序前数组为:"+ Arrays.toString(arr));
        mergeSort(arr,0,arr.length-1,temp);
        System.out.println("排序后数组为:"+ Arrays.toString(arr));
    }
    public static void mergeSort(int[] arr,int left,int right,int[] temp){
        if (left<right){
            int mid = (left+right)/2;//中间索引
            //向左递归进行分解
            mergeSort(arr,left,mid,temp);
            //向右递归
            mergeSort(arr,mid+1,right,temp);
            //合并
            merge(arr,left,mid,right,temp);
        }
    }
    public static void merge(int[] arr,int left,int mid,int right,int[] temp){
        int i = left;//初始化i,左边有序序列的初始索引
        int j = mid + 1;//初始化j,右边有序序列的初始索引
        int t = 0;//指向temp数组的当前索引
        //1.先把左右两边(有序)的数据按照规则填充到temp数组,知道左右两边的有序序列又一边处理完为止
        while (i<=mid&&j<=right){
            if (arr[i]<arr[j]){
                temp[t] = arr[i];
                t+=1;
                i+=1;
            }else {
                temp[t] = arr[j];
                t+=1;
                j+=1;
            }

        }
        //2.把还有剩余数据的一边剩下的树填充到temp
        while(i<=mid){
            temp[t] = arr[i];
            t++;
            i++;
        }
        while (j<=right){
            temp[t] = arr[j];
            t++;
            j++;
        }
        //3.将temp数组的元素拷贝到arr
        //注意,不是每次都拷贝所有
        t = 0;
        int tempLeft = left;
        while (tempLeft <= right){
            arr[tempLeft] = temp[t];
            t++;
            tempLeft++;
        }

    }
}

她写了一个临时数组temp用来暂时存储’分’时排序的数组
比如左半边分到最后是[8],[4],然后在temp里{4,8}
在temp里先合起来,排一下序,他这里是使用了while进行排序,取出数,while循环比较找个合适的地方插进去,像插值排序。但他每次只循环该分支的部分,然后排好序了再把该段赋给arr
刚开始是两个值的循环,赋好值后,往上跳一层,四个值循环
左temp{4,5,7,8} arr{4,5,7,8,1,3,2,6}
右temp{1,2,3,6} arr{4,5,7,8,1,2,3,6}
再网上跳一层
{1,2,3,4,5,6,7,8}

他这个治的部分写的很好,我想不出来,重复看了两遍也只能是通过debug看懂他在干嘛,但能直接写出来还是很厉害的,这个代码我选择死记硬背一下,for 面试。

这个算法我GitHub上也有,但我把全部代码已经复制过来了,debug测试用这里的就好

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值