数据结构(Java)-排序算法-归并排序

归并排序介绍

        归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治divide-and-conquer)策略(分治法将问题(divide)成一些小的问题然后递归求解,而(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)

         合并的细节需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8][1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤

 代码思路

        归并排序可分为两个部分:分组+合并。其中分组比较简单,分别对序列左边、右半部分递归分组即可。关键在于合并,下面是和并的思路:

        1.定义两个指针,分别指向某个序列的首位中间+1的位置,其实就是两个子序列的首位。

        2.定义一个临时变量 temp,存放中间结果

        2.两个子序列中的元素 >> temp

                2.1 对比两指针所指元素的大小,挑出较小者送入temp,被挑走元素的序列的指针后移一位。

                2.2 重复2.1的操作,直到某个子序列的指针移到其末尾

        3.现在只剩下某个序列的若干元素,它们是有序且较大的。再依次把他们送入temp即可。

        4.移动完所有元素后再把temp的元素重新送回原始序列即可。

代码演示

//合并两个有序列表(形式上)为一个新列表
    public static void Merge(Integer[] arr,Integer left,Integer mid,Integer right){
        int i=left;//左半部分的指针
        int j=mid+1;//右半部分的指针
        Integer[] temp= new Integer[arr.length];
        int index=0;//temp的索引,用于添加数据
        //对比两个指针所指元素的大小,把小的存在temp中。直到有一个序列处理完
        while(i<=mid && j<=right){
            if(arr[i]<=arr[j]) temp[index++]=arr[i++];
            else temp[index++]=arr[j++];
        }
        //要注意不一定两个指针同时到达各自序列的尾部,可能还剩某个序列的若干元素
        //所以要把可能遗漏的元素加进temp
        while(i<=mid){
            temp[index++]=arr[i++];
        }
        while(j<=right){
            temp[index++]=arr[j++];
        }
        //temp已经是排序后的arr了,完成任务,我们要把temp中的数据还给arr
        index=0;
        int k=left;
        while(k<=right){
            arr[k++]=temp[index++];
        }
    }
    public static Integer[] MergeSort(Integer[] arr,Integer left,Integer right){
        //不断分割,直到left=right,就是每组只有一个元素时停止
        if(left<right){
            //二路归并,每次把序列分成两个子序列
            int mid=(left+right)/2;
            MergeSort(arr,left,mid);
            MergeSort(arr,mid+1,right);
            Merge(arr,left,mid,right);
        }
        return arr;
    }

 @Test
    public void testSort(){
        Integer[] arr = init();
        System.out.println("原始数据为:");
        print(arr);
        Long beginTime= System.currentTimeMillis();
        Integer[] result = MergeSort(arr,0,arr.length-1);
        Long endTime= System.currentTimeMillis();
        System.out.println("排序结果为:");
        print(result);
        System.out.println("耗时:"+(endTime-beginTime)+" ms");
    }

总结

         归并=分组+合并,重点是合并!要注意这里的边界值实际上就是数组索引值,要遍历的到,所以合并过程中的循环操作都是带 ”=“ 的,忽略掉就会报错或者是错误的结果!惨痛的教训。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值