zoukankan      html  css  js  c++  java
  • 记归并排序与其先赋值后自增问题

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

    归并排序

    • 归并排序的理论就不叙述了,直接不如正题。
    • 一个例子示例什么是归并排序:
      原始数组
    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++ 操作是在赋值后进行的!!

  • 相关阅读:
    正则表达式
    正则表达式的lastIndex属性
    vuejs 在移动端调起键盘并触发‘前往’按钮
    适配手机端之 rem
    prototype和_proto_
    ES6 class的继承-学习笔记
    js-null 、undefined
    ES6 class的基本语法-学习笔记
    chrome插件 - Manifest文件中的 background
    别踩白块
  • 原文地址:https://www.cnblogs.com/yangfan-123/p/11733120.html
Copyright © 2011-2022 走看看