日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Java使用DualPivotQuicksort排序

瀏覽:167日期:2022-08-14 16:57:05
Java排序 - DualPivotQuicksort

這里描述 leftmost = true 的情況,也就是會從數組的開始一直排序到數組的結尾。

數組類型:int[]、long[]、short[]、char[]、float[]、double[],還有比較特殊的 byte[]

1. 插入排序(insertion sort)

適合長度短的數組排序,對于byte[] 長度小于等于30 和 其它數組長度小于47 的情況,會使用這種排序

代碼以 int[] a 為例:

// 第一次循環i=j=0,之后每次循環j=i.// j = ++i相當于在每次循環的最后執行 {i++; j = i;}// j = i++相當于在每次循環的最后執行 {j = i; i++;}for (int i = 0, j = i; i < (length - 1); j = ++i) { int ai = a[i + 1]; // 每次循環的目的是將下一個數排到它應該在的位置,這里ai就是下一個數 while (ai < a[j]) { // while循環的目的是確定j的值 和 把所有比ai大的項向后移一位來騰出ai的位置a[j + 1] = a[j]; // 把比ai大的項向后移一位if (j-- == left) { // j-- 確定j的值,也就是確定ai的位置, j 可能等于 -1 break;} } a[j + 1] = ai; // j+1 就是ai的位置}2. 計數排序(counting sort)

只針對byte[] 長度大于30的情況,因為byte的范圍是[-128, 127],只有256個數,所以循環會利用這點

int[] count = new int[256];// 第一次循環:計數for (int i = (0 - 1); ++i <= (length - 1); count[a[i] - (-128)]++);// 第二次循環:給 < byte[] a > 賦值// 循環結束條件以k為標準,k<=0就會停止;// 因為i和k沒有固定關系,所以沒有增量表達式,但在方法體中利用--i和--k進行增量。for (int i = 256, k = length; k > 0; ) { while (count[--i] == 0); // 如果計數個數為0,什么也不做,--i byte value = (byte) (i + (-128)); int s = count[i]; do {a[--k] = value; } while (--s > 0);}3. 快速排序(Quicksort)

適合長度短的數組排序,插入排序也是快速排序的一種。對于byte[] 長度大于30的情況會使用 計數排序,不是這種排序。而對于其它數組長度大于等于47并且小于286 的情況,會使用這種排序。

3.1 對數組做近似7等分

// 7等分一段的長度近似值int seventh = (length >> 3) + (length >> 6) + 1;// 一個數組分為7段,則有五個切割點,如下為五個切割點的下標int e3 = (left + right) >>> 1; // The midpointint e2 = e3 - seventh;int e1 = e2 - seventh;int e4 = e3 + seventh;int e5 = e4 + seventh;3.2 對五個切割點進行插入排序

// Sort these elements using insertion sortif (a[e2] < a[e1]) { int t = a[e2]; a[e2] = a[e1]; a[e1] = t; }if (a[e3] < a[e2]) { int t = a[e3]; a[e3] = a[e2]; a[e2] = t; if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }}if (a[e4] < a[e3]) { int t = a[e4]; a[e4] = a[e3]; a[e3] = t; if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } }}if (a[e5] < a[e4]) { int t = a[e5]; a[e5] = a[e4]; a[e4] = t; if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t;if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }} }}3.3 創建兩個變量作為下標記錄值

// 中心部分第一個元素的索引int less = left;// 右部分第一個元素前的索引int great = right;3.4 五個切割點的值都不相同的情況

這種情況會將排序分三塊,變量 pivot1 和 pivot2 作為三塊區域值的區分:第一塊區域所有的值都 < pivot1第二塊區域所有的值都 >= pivot1 并且 <= pivot2第三塊區域所有的值都 > pivot2

3.4.1 第一塊和第三塊處理

// 取兩個值作為分區值int pivot1 = a[e2];int pivot2 = a[e4];// 要排序的第一個和最后一個元素被移動到以前由樞軸占據的位置。// 當分區完成時,軸心點被交換回它們的最終位置,并從隨后的排序中排除。a[e2] = a[left];a[e4] = a[right];// less一開始等于left, great一開始等于right。// 跳過小于或大于分割值的元素。while (a[++less] < pivot1); // 沒有判斷第一個while (a[--great] > pivot2); // 沒有判斷最后一個// 循環帶outer:,`break outer;`會跳出整個循環,也就是結束整個下面的for循環。// less不參與循環,只是一開始給k賦值,less的變化始終是`++less`,用來交換數組中的值。outer:for (int k = less - 1; ++k <= great; ) { int ak = a[k]; if (ak < pivot1) { // Move a[k] to left parta[k] = a[less];/* * Here and below we use 'a[i] = b; i++;' instead * of 'a[i++] = b;' due to performance issue. */a[less] = ak;++less; } else if (ak > pivot2) { // Move a[k] to right partwhile (a[great] > pivot2) { if (great-- == k) {break outer; }}if (a[great] < pivot1) { // a[great] <= pivot2 a[k] = a[less]; a[less] = a[great]; ++less;} else { // pivot1 <= a[great] <= pivot2 a[k] = a[great];}/* * Here and below we use 'a[i] = b; i--;' instead * of 'a[i--] = b;' due to performance issue. */a[great] = ak;--great; }}// 循環結束,交換left和(less - 1)的值,也就是處理循環前`a[e2] = a[left];`導致的分區錯誤a[left] = a[less - 1]; a[less - 1] = pivot1;// 循環結束,交換right和(great + 1)的值,也就是處理循環前`a[e4] = a[right];`導致的分區錯誤a[right] = a[great + 1]; a[great + 1] = pivot2;// 分為三部分后,嵌套排序第一部分和第三部分sort(a, left, less - 2, leftmost);sort(a, great + 2, right, false);3.4.2 第二塊處理

分兩種情況:如果第二塊剩余項超過數組要排序總長度的4/7,會將等于pivot1和等于pivot2的值取出來,再次縮減less和great中間的部分,然后進行排序。否則直接排序。

if (less < e1 && e5 < great) { // 剩余的中間部分超過4/7 /* * Skip elements, which are equal to pivot values. */ while (a[less] == pivot1) {++less; } while (a[great] == pivot2) {--great; } outer: for (int k = less - 1; ++k <= great; ) {int ak = a[k];if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; ++less;} else if (ak == pivot2) { // Move a[k] to right part while (a[great] == pivot2) {if (great-- == k) { break outer;} } if (a[great] == pivot1) { // a[great] < pivot2a[k] = a[less];a[less] = pivot1;++less; } else { // pivot1 < a[great] < pivot2a[k] = a[great]; } a[great] = ak; --great;} }}// Sort center part recursivelysort(a, less, great, false);3.5 五個切割點的值有相同的情況(單軸分區 Partitioning with one pivot)

這種情況也可以理解為將排序分三塊,但只需要一個變量 pivot 作為三塊區域值的區分:第一塊區域所有的值都 < pivot第二塊區域所有的值都 = pivot,因為這塊區域的值都相等,最后就可以不用排序第三塊區域所有的值都 > pivot

// 取下標在中間的值做一個臨時變量,該變量是中值的廉價近似值,作為分割值int pivot = a[e3];// less一開始等于left, great一開始等于right。// 方法體內部不斷修改great的值,使循環執行的次數不斷的縮減,一次循環great可以減少0,可以減少1,可以減少n。// less并不影響循環,只是作為臨時變量進行數組中值的交換,始終小于等于k,一次循環只能加1或不加。for (int k = less; k <= great; ++k) { if (a[k] == pivot) { // 如果a[k]的值等于分割值,跳過continue; } int ak = a[k]; // 取出a[k]值賦給臨時變量ak if (ak < pivot) { // Move a[k] to left parta[k] = a[less];a[less] = ak;++less; } else { // a[k] > pivot - Move a[k] to right partwhile (a[great] > pivot) { --great;}if (a[great] < pivot) { // a[great] <= pivot a[k] = a[less]; a[less] = a[great]; ++less;} else { // a[great] == pivot /* * Even though a[great] equals to pivot, the * assignment a[k] = pivot may be incorrect, * if a[great] and pivot are floating-point * zeros of different signs. Therefore in float * and double sorting methods we have to use * more accurate assignment a[k] = a[great]. */ a[k] = pivot;}a[great] = ak;--great; }}// 分為三部分后,嵌套排序第一部分和第三部分sort(a, left, less - 1, leftmost);sort(a, great + 1, right, false);4. 合并排序(merge sort)

長度很長的數組排序,對于其它數組長度大于等于286 的情況,會使用這種排序。

兩個關鍵常量,起控制作用

// 合并排序中的最大運行次數static final int MAX_RUN_COUNT = 67;// 合并排序中運行的最大長度static final int MAX_RUN_LENGTH = 33;

排序方法

/** * 長度大于等于286的int數組排序 * * @param a * 要排序int數組 * @param left * 起始下標 * @param right * 結束下標 * @param work * null * @param workBase * 0 * @param workLen * 0 */private static void largeSort(int[] a, int left, int right, int[] work,int workBase, int workLen) { /* * 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 elementrun[++count] = right; } else if (count == 1) { // The array is already sortedreturn; } // 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;}}

以上就是Java使用DualPivotQuicksort排序的詳細內容,更多關于DualPivotQuicksort排序的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲婷婷丁香| 秋霞影院一区二区三区| 亚洲精品电影| 中文亚洲欧美| 日韩精品视频一区二区三区| 日本强好片久久久久久aaa| 免费人成黄页网站在线一区二区 | 欧美在线黄色| 国产精品片aa在线观看 | 久久久久久美女精品| 亚洲天堂久久| 亚洲深深色噜噜狠狠爱网站| 日韩激情网站| 丰满少妇一区| 国产一区日韩欧美| 日韩中文字幕不卡| 国产精品亚洲综合在线观看| 红杏一区二区三区| 婷婷综合亚洲| 国产精品一区二区中文字幕| 日韩欧美午夜| 日韩在线网址| 日韩在线中文| 中文字幕av一区二区三区人| 日韩欧美激情电影| 国产91在线精品| 99国产精品久久久久久久成人热| 麻豆精品网站| 久久xxx视频| 99pao成人国产永久免费视频 | 日韩在线视频一区二区三区| 国产精品99久久久久久董美香| 久久天堂av| 日本va欧美va精品| 久久激情网站| 国产日韩欧美三级| 久久精品动漫| 国产亚洲电影| 99久久亚洲精品蜜臀| 亚洲精品一级| 91精品蜜臀一区二区三区在线| 日韩中文欧美在线| 日韩在线欧美| 国产麻豆一区二区三区精品视频| 久久要要av| 国产午夜久久av| 一本一本久久| 久久久久久一区二区| 亚洲在线久久| 亚洲一级特黄| 欧美激情精品| 亚州精品视频| 激情综合网站| 精品三区视频| 香蕉久久久久久| 蜜臀av免费一区二区三区| 国产乱码精品一区二区亚洲| 日韩午夜高潮| 三级在线看中文字幕完整版| 青青伊人久久| 亚洲免费婷婷| 国产伊人精品| 日韩欧美1区| 免费在线成人| 日韩国产精品久久久久久亚洲| 午夜精品婷婷| 日韩欧美午夜| 久久久久久一区二区| 91国内精品| 亚洲丝袜美腿一区| 国产一区白浆| 欧美+日本+国产+在线a∨观看| 久久精品一区二区三区中文字幕| 最新亚洲国产| 免费一区二区视频| 在线一区视频| 九九久久婷婷| 久久久精品久久久久久96| 国产一区精品福利| 国产精品1区| 日韩精品五月天| 亚洲深深色噜噜狠狠爱网站 | 国产va在线视频| 久久99影视| 国产精品免费99久久久| 91精品日本| 日本欧美大码aⅴ在线播放| 蜜臀va亚洲va欧美va天堂 | 欧洲毛片在线视频免费观看| 国产96在线亚洲| 精品国产aⅴ| 精品国产欧美日韩| 精品视频国产| 亚洲综合在线电影| 热三久草你在线| 久久婷婷激情| 亚洲特色特黄| 亚洲免费成人| 蜜臀久久99精品久久久久宅男| 老司机久久99久久精品播放免费| 欧美另类综合| 国产免费成人| 五月亚洲婷婷 | 日韩av自拍| 丁香六月综合| 99久久精品费精品国产| 999国产精品999久久久久久| 久久精品国产68国产精品亚洲| 中文字幕色婷婷在线视频| 在线亚洲人成| 99视频一区| 日韩精品五月天| 欧美国产不卡| 久久久久国产精品一区二区| 亚洲午夜电影| 亚洲精品欧美| 国产精品亚洲片在线播放| 美女毛片一区二区三区四区最新中文字幕亚洲| 老鸭窝一区二区久久精品| 岛国精品一区| 在线日韩av| 亚洲精品少妇| 精品国产中文字幕第一页| 国际精品欧美精品| 久久中文视频| 97se亚洲| 91精品韩国| 亚洲人亚洲人色久| 精品理论电影在线| 婷婷综合社区| 欧美专区一区| 久久九九精品| 欧美一区激情| 久久精品主播| 国产日韩欧美三区| 久久亚洲专区| 久久黄色影视| 欧美69视频| 男人的天堂亚洲一区| 国产私拍福利精品视频二区| 9999国产精品| 亚洲乱码一区| 九色porny丨国产首页在线| 久久国产88| 精品午夜久久| 美女精品一区| 国产一区丝袜| 天堂成人国产精品一区| 精品黄色一级片| 免费观看久久久4p| 97精品国产福利一区二区三区| 蜜桃一区二区三区在线观看| 久久字幕精品一区| 欧美精品一卡| 国产一区二区三区精品在线观看| 伊人久久大香线蕉av超碰演员| 国产精品主播在线观看| 国内精品福利| 另类欧美日韩国产在线| 精品91久久久久| 九九久久国产| 日韩av影院| 午夜在线视频观看日韩17c| 成人国产精品一区二区免费麻豆| 久久午夜精品| 偷拍精品精品一区二区三区| 日韩精品久久理论片| 伊人久久大香线蕉av不卡| 欧美亚洲三区| 99国产精品视频免费观看一公开 | 国产精品v日韩精品v欧美精品网站 | 欧美成人精品午夜一区二区| 午夜精品亚洲| 久久精品福利| 久久精品99国产精品| 视频一区在线视频| 美女少妇全过程你懂的久久| 91亚洲一区| 久久97视频| 国产日韩一区二区三免费高清| 亚洲黄色在线| 久久精品不卡| 在线人成日本视频| 欧美国产不卡| 日韩毛片网站| 久久av在线| 亚洲神马久久| 欧美日韩日本国产亚洲在线| 国产精品精品| 国产一区二区三区视频在线| 国产色噜噜噜91在线精品| 爽好久久久欧美精品| 亚洲精品97| 欧美日韩一区二区三区视频播放| 狠狠久久伊人中文字幕| 久久av网址| 精品国产一区二| 成人在线观看免费视频| 久久99国产精品视频| 国产精品免费不|