记归并排序与其先赋值后自增问题

记归并排序与其先赋值后自增问题

归并排序

  • 归并排序的理论就不叙述了,直接不如正题。
  • 一个例子示例什么是归并排序:
    原始数组
  1. 先讲数组划分为左右两个子表:
    2
  2. 然后继续左右两个子表拆分:
    3
  3. 对最后的拆分的子表,两两进行排序:
    4
  4. 对有序的子表进行排序和比较合并:
    5
  5. 对合并后的子表继续比较合并:
  • 可能前面的分割很清楚,但是后面的合并就有些模糊了,是怎么进行合并的呢?看代码:
/**
 * 类说明:归并排序
 */
public class MergeSort {
    public static int[] sort(int[] array) {分割排序
        if(array.length<=MakeArray.THRESHOLD){
            return InsertionSort.sort(array);  //简单的插入排序
        }else{
            /*切分数组,然后递归调用*/
            int mid = array.length / 2;
            int[] left = Arrays.copyOfRange(array, 0, mid);
            int[] right = Arrays.copyOfRange(array, mid, array.length);
            return merge(sort(left), sort(right));
        }
    }
    /**
     * 归并排序——将两段排序好的数组结合成一个排序数组
     *
     * @param left
     * @param right
     * @return
     */
    public static int[] merge(int[] left, int[] right) {//合并
        int[] result = new int[left.length + right.length];
        for (int index = 0, i = 0, j = 0; index < result.length; index++) {
            if (i >= left.length)/*左边数组已经取完,完全取右边数组的值即可*/
                result[index] = right[j++];
            else if (j >= right.length)/*右边数组已经取完,完全取左边数组的值即可*/
                result[index] = left[i++];
            else if (left[i] > right[j])/*左边数组的元素值大于右边数组,取右边数组的值*/
                result[index] = right[j++];
            else/*右边数组的元素值大于左边数组,取左边数组的值*/
                result[index] = left[i++];
        }

        return result;
    }

    public static void main(String[] args) {
        System.out.println("============================================");
        long start = System.currentTimeMillis();
        MergeSort.sort(MakeArray.makeArray());
        System.out.println(" spend time:"+(System.currentTimeMillis()-start)+"ms");
    }
}

  • 重点看merge函数部分:
public static int[] merge(int[] left, int[] right) {//合并
        int[] result = new int[left.length + right.length];
        for (int index = 0, i = 0, j = 0; index < result.length; index++) {
            if (i >= left.length)/*左边数组已经取完,完全取右边数组的值即可*/
                result[index] = right[j++];
            else if (j >= right.length)/*右边数组已经取完,完全取左边数组的值即可*/
                result[index] = left[i++];
            else if (left[i] > right[j])/*左边数组的元素值大于右边数组,取右边数组的值*/
                result[index] = right[j++];
            else/*右边数组的元素值大于左边数组,取左边数组的值*/
                result[index] = left[i++];
        }
        return result;
    }
  • 这是一个升序的,上面的例子是降序。他是这样进行合并排序的。

  • 好了合并排序弄明白了,剩下的也就是递归回去了。

  • 但是发现这个代码中又有一个的点: result[index] = right[j++];,为什么会是j++不是应该是result[index] = right[j]吗?后来一想,应该是,但是只不过j的自增是在赋值后操作的!

result[index] = right[j]赋值后自增

  • 证明:
/**
 *CLASSNAME:Test
 * 测试排序中的 i++
 * 如: result[index] = right[j++]; 新数组中的元素是等于right中的第一个元素还是第二个元素(假设j=0)
 */
public class Test {

    public static void main(String[] args) {
        int[] result = new int[5];
        int[] right = {1,2,3,4,5};

        System.out.println("初始数组:");
        System.out.println("=======================================");
        System.out.println(result.toString());
        for (int i = 0, j = 0; i < result.length; i++){
//            if (j > right.length){
                //right数组会出现越界吗?在这里肯定不会,因为result的长度也是5,会先退出循环而不会执行到取right[j++]这个地方
//                System.out.println("结束!");
//            }else{
                System.out.println("right["+j+"] = " +right[j]);
                result[i] = right[j++];
                System.out.println("result["+i+"] = "+result[i]);
//            }
        }
    }
}

  • 结果:

  • 可以发现 j++ 操作是在赋值后进行的!!

原文地址:https://www.cnblogs.com/yangfan-123/p/11733120.html