【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

你可能感兴趣的:(Java学习笔记,java,排序算法,算法)