91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Arrays.sort(arr)代碼邏輯是什么

發布時間:2022-02-07 10:28:11 來源:億速云 閱讀:153 作者:iii 欄目:開發技術

本篇內容介紹了“Arrays.sort(arr)代碼邏輯是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

首先看源碼:

 public static void sort(int[] a) {
        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
    }

它調用了DualPivotQuicksort的sort方法,乍一看以為是快排,這是很多網上的博主的說法,繼續點開向下看(代碼太長,沒耐心看可以直接跳過該段代碼QWQ):

 static void sort(int[] a, int left, int right,
                     int[] work, int workBase, int workLen) {
        // Use Quicksort on small arrays
        if (right - left < QUICKSORT_THRESHOLD) {
            sort(a, left, right, true);
            return;
        }
        /*
         * Index run[i] is the start of i-th run
         * (ascending or descending sequence).
         */
        int[] run = new int[MAX_RUN_COUNT + 1];
        int count = 0; run[0] = left;
        // 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;
            }
        }
        // Check special cases
        // Implementation note: variable "right" is increased by 1.
        if (run[count] == right++) { // The last run contains one element
            run[++count] = right;
        } else if (count == 1) { // The array is already sorted
            return;
        }
        // Determine alternation base for merge
        byte odd = 0;
        for (int n = 1; (n <<= 1) < count; odd ^= 1);
        // Use or create temporary array b for merging
        int[] b;                 // temp array; alternates with a
        int ao, bo;              // array offsets from 'left'
        int blen = right - left; // space needed for b
        if (work == null || workLen < blen || workBase + blen > work.length) {
            work = new int[blen];
            workBase = 0;
        }
        if (odd == 0) {
            System.arraycopy(a, left, work, workBase, blen);
            b = a;
            bo = 0;
            a = work;
            ao = workBase - left;
        } else {
            b = work;
            ao = 0;
            bo = workBase - left;
        }
        // Merging
        for (int last; count > 1; count = last) {
            for (int k = (last = 0) + 2; k <= count; k += 2) {
                int hi = run[k], mi = run[k - 1];
                for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
                    if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) {
                        b[i + bo] = a[p++ + ao];
                    } else {
                        b[i + bo] = a[q++ + ao];
                    }
                }
                run[++last] = hi;
            }
            if ((count & 1) != 0) {
                for (int i = right, lo = run[count - 1]; --i >= lo;
                    b[i + bo] = a[i + ao]
                );
                run[++last] = right;
            }
            int[] t = a; a = b; b = t;
            int o = ao; ao = bo; bo = o;
        }
    }

代碼很長,簡要翻譯過來,這里分了好幾種情況:

1.數組長度小于286

這里又會調用一個sort方法,點開該sort(),又會劃分情況:

數組長度小于47,

當leftmost(導入的一個布爾參數)為true,則使用直接插入排序;

否則會調用另一種插入辦法,這里可以觀察到一個注釋:

/*
  * Every element from adjoining part plays the role
  * of sentinel, therefore this allows us to avoid the
  * left range check on each iteration. Moreover, we use
  * the more optimized algorithm, so called pair insertion
  * sort, which is faster (in the context of Quicksort)
  * than traditional implementation of insertion sort.
  */

大致意思是:相鄰部分的每個元素都扮演著哨兵的角色,因此這允許我們避免在每次迭代中進行左范圍檢查。此外,我們使用了更優化的算法,即所謂的成對插入排序,它比插入排序的傳統實現更快(在快速排序的上下文中)。

不過注意到,原函數參數傳參在這里leftmost為true,所以一定是直接插入排序,以上作為了解。

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

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

2.重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的后面(相同的數可以到任一邊)。在這個分區退出之后,該基準就處于數列的中間位置。這個稱為分區(partition)操作;

3.遞歸地(recursive)把小于基準值元素的子數列和大于基準值元素的子數列排序。

當數組長度大于286時

此時回到那段很長很長的代碼段,在判斷小于286的長度數組之后,從注解中:

// Check if the array is nearly sorted

這里是指檢查數組元素是不是快要排列好了,或者書面一點說,是不是有一定結構了,然后看后面的for循環,注意到一段代碼:

 if (++count == MAX_RUN_COUNT) {
                sort(a, left, right, true);
                return;
            }

這里的sort和我們上面在數組長度小于286時的那個sort方法是同一個方法,而針對這個count,是用來記錄逆序組的,打個比方:

此時有一個數組為1 5 6 9 8 7 2 3

當數組認定我們的順序應該為升序時,從第一個數開始數,此時9 8 7 2為降序,這就是逆序,將這四個數組合成一個組稱為逆序組,然后再從3開始往后看。

當統計到一個逆序組時,count++,所以可以看出,count是用來記逆序組的,那么逆序組越多,這個結構就越混亂

MAX_RUN_COUNT == 67 ,因此當count一直加到67時,就說明已經在一個混亂的臨界值了,此時執行sort()方法

通過這一段分析,我們理一下思路:

如果數組能運行到這里,說明數組的長度大于等于286。符合該條件時,我們要判斷這個數組是否有一定的結構:

(1)count<67,說明不是那么混亂,有一定結構,跳過;

(2)count>=67,說明已經混亂了,沒有結構,執行sort方法,而已知數組長度大于等于286,那么必然大于47,一定執行快速排序。

跳過之后,經過代碼的一大堆前置操作,最后看見下面的代碼里面一行注釋:

//Merging

顯然,這里后面用到歸并排序了,不詳細贅述。

好了,最后總結:

  • 數組長度小于286時,根據數組長度,分兩種情況:

    • 數組長度小于47,使用直接插入排序

    • 數組長度大于47,使用快速排序

  • 數組長度大于286時,根據數組排序情況,分兩種情況:

    • 數組內順序較為混亂,即count逆序組數大于等于67,使用快速排序

    • 數組內有一定順序,即count逆序組數小于67,使用歸并排序

“Arrays.sort(arr)代碼邏輯是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

胶南市| 雷波县| 葫芦岛市| 镇沅| 马尔康县| 双流县| 望奎县| 西乌| 景德镇市| 蒙自县| 衡东县| 正定县| 丰顺县| 高阳县| 明水县| 新田县| 日喀则市| 宜丰县| 望谟县| 循化| 金乡县| 临江市| 义乌市| 虞城县| 定结县| 阿克陶县| 嘉义县| 秀山| 江门市| 浦城县| 黄骅市| 腾冲县| 民县| 麻阳| 云梦县| 清水河县| 长白| 昆山市| 清原| 华蓥市| 闸北区|