zoukankan      html  css  js  c++  java
  • Comparator的compare方法如何定义升序降序

    最近做算法题用了Comparator接口下的compare方法,思考了一下升序和降序的规则是如何来的,现在做一个补充,方便以后回顾。

     升序代码

        public static void main(String[] args) {
            Integer[] nums = new Integer[]{6, 8, 3, 0, 2};
            Arrays.sort(nums, new Comparator<Integer>() {
    
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1 - o2;
                }
            });
            for (Integer i : nums) {
                System.out.print(i + "  ");
            }
        }

    降序代码

        public static void main(String[] args) {
            Integer[] nums = new Integer[]{6, 8, 3, 0, 2};
            Arrays.sort(nums, new Comparator<Integer>() {
    
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o2 - o1;
                }
            });
            for (Integer i : nums) {
                System.out.print(i + "  ");
            }
        }

    所以更多时候我们是直接记住了compare(int o1, int o2)方法 return o1 - o2 是升序,return o2 - o1 是降序。那么原因我们不妨跳进去源码看一下

        public static <T> void sort(T[] a, Comparator<? super T> c) {
            if (c == null) {
                sort(a);
            } else {
                if (LegacyMergeSort.userRequested)
                    legacyMergeSort(a, c);
                else
                    TimSort.sort(a, 0, a.length, c, null, 0, 0);
            }
        }

    可以看出他是进去了else内,不妨先进入legacyMergeSort看一下

        private static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) {
            T[] aux = a.clone();
            if (c==null)
                mergeSort(aux, a, 0, a.length, 0);
            else
                mergeSort(aux, a, 0, a.length, 0, c);
        }

    这里很明显也是进去了else内,继续看mergeSort

        private static void mergeSort(Object[] src,
                                      Object[] dest,
                                      int low, int high, int off,
                                      Comparator c) {
            int length = high - low;
    
            // Insertion sort on smallest arrays
            if (length < INSERTIONSORT_THRESHOLD) {
                for (int i=low; i<high; i++)
                    for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                        swap(dest, j, j-1);
                return;
            }
    
            // Recursively sort halves of dest into src
            int destLow  = low;
            int destHigh = high;
            low  += off;
            high += off;
            int mid = (low + high) >>> 1;
            mergeSort(dest, src, low, mid, -off, c);
            mergeSort(dest, src, mid, high, -off, c);
    
            // If list is already sorted, just copy from src to dest.  This is an
            // optimization that results in faster sorts for nearly ordered lists.
            if (c.compare(src[mid-1], src[mid]) <= 0) {
               System.arraycopy(src, low, dest, destLow, length);
               return;
            }
    
            // Merge sorted halves (now in src) into dest
            for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
                if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
                    dest[i] = src[p++];
                else
                    dest[i] = src[q++];
            }
        }

    这一段的代码关键就是如下部分

            if (length < INSERTIONSORT_THRESHOLD) {
                for (int i=low; i<high; i++)
                    for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                        swap(dest, j, j-1);
                return;
            }

    可以看到这里面调用了compare方法,当方法的返回值大于0的时候就将数组的前一个数和后一个数做交换。以升序为例来讲解,升序的话compare方法就 return o1 - o2,那么就是 return dest[j-1] - dest[j]。

    当 dest[j-1] > dest[j] 时,就进行交换。当 dest[j-1] <= dest[j] 时位置不变,从而达到数组升序。降序也是一样的道理,就不多讲了。

  • 相关阅读:
    [資料]VS2008技巧
    [資料]MarshalAs的用法
    MS SQL Server 2000安装不成功的原因
    Zend產品線
    [轉]Flex 开发必备10武器
    [轉]C#中的XML注释
    [轉]onpropertychange事件
    [轉]fckeditor添加自定义按钮
    [資源]Web設計資源以及线框工具
    [轉]JS中showModalDialog 详细使用
  • 原文地址:https://www.cnblogs.com/lzxin/p/11326481.html
Copyright © 2011-2022 走看看