【Java学习笔记】归并排序的实现

【Java学习笔记】归并排序的实现

参考了百度百科关于归并排序的论述

归并排序不难理解,你需要知道:

  • 一个只有一个数字的“数组”,是已经排好序的;
  • 把两个已经排好序的数组,拼一块排序,其实是很简单、很迅速的;
  • 任何长度的数组,都可以用很多的这个一个数字的“数组”两两拼接。

两两拼接的过程,就叫***归并***。

我们需要一个递归的方法来实现这个拼接过程:

//这个方法搭建了一个框架,实现了分治的思想。排序前数组为disorderArray,排序完成的数组为orderArray
    public static void mergeSort(int[] disorderArray,int[] orderArray,int left,int right){
        //中点索引位置
        int mid = (left + right)/2;
        //递归的条件:左右两边至少有2个元素,当只有1个元素时,必为有序”数组“。
        if(mid > left){
            mergeSort(disorderArray,orderArray,left,mid);
        }
        if((mid + 1) < right){
            mergeSort(disorderArray,orderArray,mid+1,right);
        }
        //分割完毕,下层递归执行完毕,左右两边均为有序数组。
        sort(disorderArray,orderArray,left,right);
    }

我们还需要一个方法来实现把两个已经排好序的数组,拼一块排序的过程:

//这个方法是核心,排序前数组为disorderArray,排序完成的数组为orderArray。
    //已知左右两边都是有序的,将两边的有序数组结合为统一有序的数组。
    public static void sort(int[] disorderArray,int[] orderArray,int left,int right){
        //中点索引位置
        int mid = (left + right)/2;
        //i,j分别为排序前数组的左右索引位置,k为排序后数组的索引位置
        int i = left;
        int j = mid + 1;
        int k = left;
        //判断i、j索引是否到边界。如果i到了边界,就把当前j索引以后的所有值填入。反之亦然
        boolean iIsOut = false;
        boolean jIsOut = false;
        //循环结束条件:k值超过索引位置。
        do{
            //这里一共有四个判断:
            //1.i索引出界了吗?如果出界了,那j剩下的所有值都填进去;
            //2.j索引出界了吗?如果出界了,那i剩下的所有值都填进去;
            //3.右半数组元素的小于左半数组元素?如果小,把右半放进去;
            //4.剩下的情况就是右半数组元素的大于等于于左半数组元素了,把左半放进去。
            if(iIsOut){
                orderArray[k] = disorderArray[j];
                //j,k索引位置向右移动,但j最右不能超过right索引。
                k++;
                if(j < right){
                    j++;
                }else {
                    jIsOut = true;
                }
            }else if(jIsOut){
                orderArray[k] = disorderArray[i];
                //i,k索引位置向右移动,但i最右不能超过mid索引。
                k++;
                if(i < mid){
                    i++;
                }else {
                    iIsOut = true;
                }
            }else if (disorderArray[i] > disorderArray[j]){
                //当右半元素的小于左半元素的情况。
                orderArray[k] = disorderArray[j];
                //j,k索引位置向右移动,但j最右不能超过right索引。
                k++;
                if(j < right){
                    j++;
                }else {
                    jIsOut = true;
                }
            }else {
                //当左半元素的小于或者等于右半元素的情况,归并排序的稳定就在这里体现。
                orderArray[k] = disorderArray[i];
                //i,k索引位置向右移动,但i最右不能超过mid索引。
                k++;
                if(i < mid){
                    i++;
                }else {
                    iIsOut = true;
                }
            }
        }while (k < right + 1);
        //将排好序的数组赋值给未排序的数组。
        for (int l = left; l <= right; l++) {
            disorderArray[l] = orderArray[l];
        }
    }

如此,你就完成了归并排序。20200623

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值