zoukankan      html  css  js  c++  java
  • Arrays.sort()原理

    参考:【todo】

    https://blog.csdn.net/realYuzhou/article/details/109299625

    https://blog.csdn.net/duuuhs/article/details/89167231

    https://www.jianshu.com/p/e2b7256163ae

    Arrays.sort使用的排序算法

    java中Arrays.sort使用了两种排序方法,快速排序和优化的归并排序。

    快速排序主要是对哪些基本类型数据(int,short,long等)排序, 而合并排序用于对对象类型进行排序。使用不同类型的排序算法主要是由于快速排序是不稳定的,而合并排序是稳定的

    归并排序相对而言比较次数比快速排序少,移动(对象引用的移动)次数比快速排序多,而对于对象来说,比较一般比移动耗时。补充一点合并排序的时间复杂度是nlogn, 快速排序的平均时间复杂度也是nlogn,但是合并排序的需要额外的n个引用的空间。

    import java.util.Arrays;
    import java.util.Comparator;
    
    public class ArraySort {
        public static void main(String[] args) {
            Dog d2 = new Dog(2);
            Dog d1 = new Dog(1);
            Dog d3 = new Dog(3);
            Dog[] dogArray = {d3,d1,d2};
            printDog(dogArray);
            Arrays.sort(dogArray,new DogSizeComparator());
            printDog(dogArray);
        }
        public  static  void  printDog(Dog[] dogs){
            for (Dog dog:dogs) {
                System.out.println(dog.size+" ");
            }
            System.out.println();
        }
    }
    
    class  Dog{
        int size;
        public  Dog(int s){
            this.size = s;
        }
    }
    
    class DogSizeComparator implements Comparator<Dog> {
        @Override
        public int compare(Dog o1, Dog o2) {
            return o1.size - o2.size;
        }
    }
    
    

    源码中的快速排序,主要做了以下几个方面的优化:
      1)当待排序的数组中的元素个数较少时,源码中的阀值为7,采用的是插入排序。尽管插入排序的时间复杂度为0(n^2),但是当数组元素较少时,插入排序优于快速排序,因为这时快速排序的递归操作影响性能。
      2)较好的选择了划分元(基准元素)。能够将数组分成大致两个相等的部分,避免出现最坏的情况。例如当数组有序的的情况下,选择第一个元素作为划分元,将使得算法的时间复杂度达到O(n^2).
      3)根据划分元 v ,形成不变式 v* (

    源码中选择划分元的方法:
     1)当数组大小为 size=7 时 ,取数组中间元素作为划分元。int n=m>>1;(此方法值得借鉴)。
     2)当数组大小size大于7小于等于40时,取首、中、末三个元素中间大小的元素作为划分元。
     3)当数组大小 size>40 时 ,从待排数组中较均匀的选择9个元素,选出一个伪中数做为划分元。
     普通的快速排序算法,经过一次划分后,将划分元排到素组较中间的位置,左边的元素小于划分元,右边的元素大于划分元,而没有将与划分元相等的元素放在其附近,这一点,在Arrays.sort()中得到了较大的优化。

    举例:15、93、15、41、6、15、22、7、15、20
       举例:15、93、15、41、6、15、22、7、15、20

    因size大于7小于等于40 ,所以在15、6、和20 中选择v = 15 作为划分元。
      经过一次换分后: 15、15、7、6、41、20、22、93、15、15. 与划分元相等的元素都移到了素组的两边。
      接下来将与划分元相等的元素移到数组中间来,形成:7、6、15、15、15、15、41、20、22、93.
      最后递归对两个区间进行排序[7、6]和[41、20、22、93].,所以在15、6、和20 中选择v = 15 作为划分元。

     
     
     
  • 相关阅读:
    《杜教筛》
    《洛谷P4213 【模板】杜教筛(Sum)》
    《洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB》
    《纸牌问题》
    《洛谷P2522 [HAOI2011]Problem b》
    使用urlretrieve下载图片
    scrapy初探
    爬豆瓣电影名
    直接插入排序
    Windows python 3 安装OpenCV
  • 原文地址:https://www.cnblogs.com/xuwc/p/13946390.html
Copyright © 2011-2022 走看看