归并排序(java实现)

基本思路:
1.整体分为分 - 治
2.分,怎么分?通过递归向下分,到只有两个数比较为止
3.治,如何治?递归回溯向上合并,在分到最底部开始,
    a.比较两个数大小,并使用一个临时数组temp临时储存
    b.如果两个序列(最少有1个值)比较完,一方序列还有值,就将剩余的全部放到临时数组temp
    c.将临时数组的值再copy到原数组

 上图:

 

下面这张图是回溯上去后最后一次合并,并不是只有一次合并

再来看上图,这次排序其实有数组长度-1次合并,分别是8 4,5 7,1 3,6 2,48 57,13 26以及下面图中的最后一次合并 4578 1236

 

 结合代码分析,再看不明白可以自己debug走几遍就清晰了

//拆分在合并
    public static void diguisort(int left,int right,int nums[],int temp[]){
        if (left<right){
            int mid=(left+right)/2;
//            向左递归
            diguisort(left,mid,nums,temp);
//            向右递归
            diguisort(mid+1,right,nums,temp);
            guisort(left,mid,right,nums,temp);
        }
    }


//    合并方法
    public static void guisort(int left,int mid,int right,int nums[],int temp[]){
//        左边序列的初始值
        int l=left;
//        右边序列的初始值
        int r=mid+1;
//        因为我们比较两个序列会把小的值暂存另一个数组,所以要有这个计数器
        int t=0;

//      (1)  左右两边值的比较
        while (l<=mid && r<=right){
//            左小于右
            if (nums[l]<=nums[r]){
//                左值赋给暂存数组
                temp[t]=nums[l];
//                暂存数组后移
                t+=1;
//                左序列后移
                l+=1;
            }else{
                temp[t]=nums[r];
                t+=1;
                r+=1;
            }
        }
//       (2) 如果有一方剩余数组将剩余数组全部放到暂存数组
//            左边序列有剩余
            while (l<=mid){
               temp[t]=nums[l];
                t+=1;
                l+=1;
            }
//            右边序列有剩余
            while (r<=right){
                temp[t]=nums[r];
                t+=1;
                r+=1;
            }
//        将temp数组copy到原数组
            t=0;
            int templeft=left;
//        System.out.println("templeft:"+templeft+" "+"right:"+right);
            while (templeft<=right){
                nums[templeft]=temp[t];
                t+=1;
                templeft+=1;
            }
    }

我们再来测试一波:

        int num[]=new int[800000];
        int temp[]=new int[num.length];
        for (int i = 0; i <num.length; i++) {
            num[i] = (int) (Math.random() * 800000);
        }
//        测试
        Date d1 = new Date();
        SimpleDateFormat s = new SimpleDateFormat("YY-MM-DD HH:mm:ss:SSS");
        String s1 = s.format(d1);
        System.out.println("排序前的时间;" + s1);

        diguisort(0, num.length-1,num,temp);
//        System.out.println(Arrays.toString(num));
        Date d2 = new Date();
        String s2 = s.format(d2);
        System.out.println("排序后时间;" + s2);

 80w数据不到200ms,跟我一样快!!!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值