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++ 操作是在赋值后进行的!!

  • 相关阅读:
    现代软件工程 第一章 概论 第4题——邓琨
    现代软件工程 第一章 概论 第9题——邓琨
    现代软件工程 第一章 概论 第7题——张星星
    现代软件工程 第一章 概论 第5题——韩婧
    hdu 5821 Ball 贪心(多校)
    hdu 1074 Doing Homework 状压dp
    hdu 1074 Doing Homework 状压dp
    hdu 1069 Monkey and Banana LIS变形
    最长上升子序列的初步学习
    hdu 1024 Max Sum Plus Plus(m段最大子列和)
  • 原文地址:https://www.cnblogs.com/yangfan-123/p/11733120.html
Copyright © 2011-2022 走看看