欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2022年02月02日 09:54:27   作者:白春雨  
網上看過很多JDK8中Arrays.sort的底層原理,有些說是插入排序,有些說是歸并排序,也有說大于域值用計數排序法,否則就使用插入排序,這種說法到底對嗎?下面通過本文給大家分析下Java的Arrays.sort()方法到底用的什么排序算法,感興趣的朋友一起看看吧

  暫時網上看過很多JDK8中Arrays.sort的底層原理,有些說是插入排序,有些說是歸并排序,也有說大于域值用計數排序法,否則就使用插入排序。。。其實不全對。讓我們分析個究竟:

// Use 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);方法:

// Use insertion sort on tiny arrays
if (length < INSERTION_SORT_THRESHOLD)
{
    if (leftmost)
    {
        ......

  點進去后我們看到第二個閥值INSERTION_SORT_THRESHOLD(47),如果元素少于47這個閥值,就用插入排序,往下看確實如此:

/*
 * Traditional (without sentinel) insertion sort,
 * optimized for server VM, is used in case 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用插入排序

  至于大過INSERTION_SORT_THRESHOLD(47)的,用一種快速排序的方法:

  1.從數列中挑出五個元素,稱為 “基準”(pivot);

  2.重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的后面(相同的數可以到任一邊)。在這個分區(qū)退出之后,該基準就處于數列的中間位置。這個稱為分區(qū)(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]);
        } else 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;
            }
        } else { // 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,
         * use 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后面繼續(xù)往后面找。

  每遇到這樣一個降序組,++count,當count大于MAX_RUN_COUNT(67),被判斷為這個數組不具備結構(也就是這數據時而升時而降),然后送給之前的sort(里面的快速排序)的方法(The array is not highly structured,use Quicksort instead of merge sort.)

  如果count少于MAX_RUN_COUNT(67)的,說明這個數組還有點結構,就繼續(xù)往下走下面的歸并排序。

總結:

  從上面分析,Arrays.sort并不是單一的排序,而是插入排序,快速排序,歸并排序三種排序的組合,為此我畫了個流程圖:

  O(nlogn)只代表增長量級,同一個量級前面的常數也可以不一樣,不同數量下面的實際運算時間也可以不一樣。

  數量非常小的情況下(就像上面說到的,少于47的),插入排序等可能會比快速排序更快。 所以數組少于47的會進入插入排序。

  快排數據越無序越快(加入隨機化后基本不會退化),平均常數最小,不需要額外空間,不穩(wěn)定排序。

  歸排速度穩(wěn)定,常數比快排略大,需要額外空間,穩(wěn)定排序。

  所以大于或等于47或少于286會進入快排,而在大于或等于286后,會有個小動作:“// Check if the array is nearly sorted”。這里第一個作用是先梳理一下數據方便后續(xù)的歸并排序,第二個作用就是即便大于286,但在降序組太多的時候(被判斷為沒有結構的數據,The array is not highly structured,use Quicksort instead of merge sort.),要轉回快速排序。

到此這篇關于Java的Arrays.sort()方法排序算法實例分析的文章就介紹到這了,更多相關Java的Arrays.sort()方法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • spring MVC搭建及配置詳解

    spring MVC搭建及配置詳解

    本篇文章主要介紹了spring MVC配置方法,要想靈活運用Spring MVC來應對大多數的Web開發(fā),就必須要掌握它的配置及原理,有興趣的可以了解一下。
    2017-01-01
  • 封裝jndi操作ldap服務器的工具類

    封裝jndi操作ldap服務器的工具類

    這篇文章主要介紹了封裝JNDI操作LDAP服務器的工具類,使用者只需要會使用List,Map 數據結構,大家參考使用吧
    2014-01-01
  • java實現砸金蛋抽獎功能

    java實現砸金蛋抽獎功能

    這篇文章主要為大家詳細介紹了java實現砸金蛋抽獎功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • 教你怎么通過IDEA設置堆內存空間

    教你怎么通過IDEA設置堆內存空間

    這篇文章主要介紹了教你怎么通過IDEA設置堆內存空間,文中有非常詳細的代碼示例,對正在使用IDEA的小伙伴們很有幫助喲,需要的朋友可以參考下
    2021-05-05
  • java實現將字符串中首字母轉換成大寫,其它全部轉換成小寫的方法示例

    java實現將字符串中首字母轉換成大寫,其它全部轉換成小寫的方法示例

    這篇文章主要介紹了java實現將字符串中首字母轉換成大寫,其它全部轉換成小寫的方法,涉及java字符串遍歷、轉換、拼接等相關操作技巧,需要的朋友可以參考下
    2019-06-06
  • Java IO流和文件操作實現過程解析

    Java IO流和文件操作實現過程解析

    這篇文章主要介紹了Java IO流和文件操作實現過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • java讀取圖片并顯示方式

    java讀取圖片并顯示方式

    這篇文章主要介紹了java讀取圖片并顯示方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Druid核心源碼解析DruidDataSource

    Druid核心源碼解析DruidDataSource

    這篇文章主要為大家介紹了Druid核心源碼解析DruidDataSource,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Spring的循環(huán)依賴、三級緩存解決方案源碼詳細解析

    Spring的循環(huán)依賴、三級緩存解決方案源碼詳細解析

    這篇文章主要介紹了Spring的循環(huán)依賴、三級緩存解決方案源碼詳細解析,在Spring中,由于IOC的控制反轉,創(chuàng)建對象不再是簡單的new出來,而是交給Spring去創(chuàng)建,會經歷一系列Bean的生命周期才創(chuàng)建出相應的對象,需要的朋友可以參考下
    2024-01-01
  • java ZXing生成二維碼及條碼實例分享

    java ZXing生成二維碼及條碼實例分享

    本文分享了java ZXing生成二維碼及條碼的實例代碼,具有很好的參考價值,需要的朋友一起來看下吧
    2016-12-12

最新評論