首页 > 作文

Java的Arrays.sort()方法排序算法实例分析

更新时间:2023-04-04 21:24:54 阅读: 评论:0

  暂时网上看过很多jdk8中arrays.sort的底层原理,有些说是插入排序,有些说是归并排序,也有说大于域值用计数排序法,否则就使用插入排序。。。其实不全对。让我们分析个究竟:

// u quicksort on small arrays耳环搭配if (right - left < quicksort_threshold){       //quicksort_threshold = 286        sort(a, left, right, true);        return; }

  数组一进来,会碰到第一个阀值quicksort_threshold(286),注解上说,小过这个阀值的进入quicksort (快速排序),其实并不全是,点进去sort(a, left, right, true);方法:

// u inrtion sort on tiny arraysif (length < inrtion_sort_threshold){    if (leftmost)    {        ......

  点进去后我们看到第二个过零丁洋原文及翻译阀值inrtion_sort_threshold(47),如果元素少于47这个阀值,就用插入排序,往下看确实如此:

/* * traditional (without ntinel) inrtion sort, * optimized for rver vm, is ud in ca of * the leftmost part. */for (int i = left, j = i; i < right; j = ++i){     int ai = a[i + 1];     while (ai < a[j])     {          a[j + 1] = a[j];          if (j-- == left)          {               break;           }      }      a[j + 1] = ai;

元素少于47用插入排序

  至于大过inrtion_sort_threshold(47)的,用一种快速排序的方法:

  1.从数列中挑出五个元素,称为 “基准”(pivot);

  2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;

  3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

快速排序(quick sort)

  这是少于阀值quicksort_threshold(286)的两种情况,至于大于286的,它会进入归并排序(merge sort),但在此之前,它有个小动作:

// check if the array is nearly sorted    for (int k = left; k < right; run[count] = k) {        if (a[k] < a[减肥日记k + 1]) { // ascending            while (++k <= right && a[k - 1] <= a[k]);        } el if (a[k] > a[k + 1]) { // descending            while (++k <= right && a[k - 1] >= a[k]);            for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {                int t = a[lo]; a[lo] = a[hi]; a[hi] = t;   dnf电脑管家         }        } el { // equal 求解           for (int m = max_run_length; ++k <= right && a[k - 1] == a[k]; ) {                if (--m == 0) {                    sort(a, left, right, true);                    return;                }            }        }        /*         * the array is not highly structured,         * u quicksort instead of merge sort.         */        if (++count == max_run_count) {            sort(a, left, right, true);            return;        }    }

  这里主要作用是看他数组具不具备结构:实际逻辑是分组排序,每降序为一个组,像1,9,8,7,6,8。9到6是降序,为一个组,然后把降序的一组排成升序:1,6,7,8,9,8。然后最后的8后面继续往后面找。

  每遇到这样一个降序组,++count,当count大于max_run_count(67),被判断为这个数组不具备结构(也就是这数据时而升时而降),然后送给之前的sort(里面的快速排序)的方法(the array is not highly structured,u quicksort instead of merge sort.)

  如果count少于max_run_count(67)的,说明这个数组还有点结构,就继续往下走下面的归并排序。

总结:

  从上面分析,arrays.sort并不是单一的排序,而是插入排序,快速排序,归并排序三种排序的组合,为此我画了个流程图:

  o(nlogn)只代表增长量级,同一个量级前面的常数也可以不一样,不同数量下面的实际运算时间也可以不一样。

  数量非常小的情况下(就像上面说到的,少于47的),插入排序等可能会比快速排序更快。 所以数组少于47的会进入插入排序。

  快排数据越无序越快(加入随机化后基本不会退化),平均常数最小,不需要额外空间,不稳定排序。

  归排速度稳定,常数比快排略大,需要额外空间,稳定排序。

  所以大于或等于47或少于286会进入快排,而在大于或等于286后,会有个小动作:“// check if the array is nearly sorted”。这里第一个作用是先梳理一下数据方便后续的归并排序,第二个作用就是即便大于286,但在降序组太多的时候(被判断为没有结构的数据,the array is not highly structured,u quicksort instead of merge sort.),要转回快速排序。

到此这篇关于java的arrays.sort()方法排序算法实例分析的文章就介绍到这了,更多相关java的arrays.sort()方法内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 21:24:52,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/bb6b829762e9bfe286bd6a582c89e1d0.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Java的Arrays.sort()方法排序算法实例分析.doc

本文 PDF 下载地址:Java的Arrays.sort()方法排序算法实例分析.pdf

标签:基准   数列   数组   元素
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图