Advertisement
Vanya_Shestakov

Arrays.sort

Dec 5th, 2020
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.34 KB | None | 0 0
  1. static void sort(Sorter sorter, int[] a, int bits, int low, int high) {
  2.         while (true) {
  3.             int end = high - 1, size = high - low;
  4.  
  5.             /*
  6.              * Run mixed insertion sort on small non-leftmost parts.
  7.              */
  8.             if (size < MAX_MIXED_INSERTION_SORT_SIZE + bits && (bits & 1) > 0) {
  9.                 mixedInsertionSort(a, low, high - 3 * ((size >> 5) << 3), high);
  10.                 return;
  11.             }
  12.  
  13.             /*
  14.              * Invoke insertion sort on small leftmost part.
  15.              */
  16.             if (size < MAX_INSERTION_SORT_SIZE) {
  17.                 insertionSort(a, low, high);
  18.                 return;
  19.             }
  20.  
  21.             /*
  22.              * Check if the whole array or large non-leftmost
  23.              * parts are nearly sorted and then merge runs.
  24.              */
  25.             if ((bits == 0 || size > MIN_TRY_MERGE_SIZE && (bits & 1) > 0)
  26.                     && tryMergeRuns(sorter, a, low, size)) {
  27.                 return;
  28.             }
  29.  
  30.             /*
  31.              * Switch to heap sort if execution
  32.              * time is becoming quadratic.
  33.              */
  34.             if ((bits += DELTA) > MAX_RECURSION_DEPTH) {
  35.                 heapSort(a, low, high);
  36.                 return;
  37.             }
  38.  
  39.             /*
  40.              * Use an inexpensive approximation of the golden ratio
  41.              * to select five sample elements and determine pivots.
  42.              */
  43.             int step = (size >> 3) * 3 + 3;
  44.  
  45.             /*
  46.              * Five elements around (and including) the central element
  47.              * will be used for pivot selection as described below. The
  48.              * unequal choice of spacing these elements was empirically
  49.              * determined to work well on a wide variety of inputs.
  50.              */
  51.             int e1 = low + step;
  52.             int e5 = end - step;
  53.             int e3 = (e1 + e5) >>> 1;
  54.             int e2 = (e1 + e3) >>> 1;
  55.             int e4 = (e3 + e5) >>> 1;
  56.             int a3 = a[e3];
  57.  
  58.             /*
  59.              * Sort these elements in place by the combination
  60.              * of 4-element sorting network and insertion sort.
  61.              *
  62.              *    5 ------o-----------o------------
  63.              *            |           |
  64.              *    4 ------|-----o-----o-----o------
  65.              *            |     |           |
  66.              *    2 ------o-----|-----o-----o------
  67.              *                  |     |
  68.              *    1 ------------o-----o------------
  69.              */
  70.             if (a[e5] < a[e2]) { int t = a[e5]; a[e5] = a[e2]; a[e2] = t; }
  71.             if (a[e4] < a[e1]) { int t = a[e4]; a[e4] = a[e1]; a[e1] = t; }
  72.             if (a[e5] < a[e4]) { int t = a[e5]; a[e5] = a[e4]; a[e4] = t; }
  73.             if (a[e2] < a[e1]) { int t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
  74.             if (a[e4] < a[e2]) { int t = a[e4]; a[e4] = a[e2]; a[e2] = t; }
  75.  
  76.             if (a3 < a[e2]) {
  77.                 if (a3 < a[e1]) {
  78.                     a[e3] = a[e2]; a[e2] = a[e1]; a[e1] = a3;
  79.                 } else {
  80.                     a[e3] = a[e2]; a[e2] = a3;
  81.                 }
  82.             } else if (a3 > a[e4]) {
  83.                 if (a3 > a[e5]) {
  84.                     a[e3] = a[e4]; a[e4] = a[e5]; a[e5] = a3;
  85.                 } else {
  86.                     a[e3] = a[e4]; a[e4] = a3;
  87.                 }
  88.             }
  89.  
  90.             // Pointers
  91.             int lower = low; // The index of the last element of the left part
  92.             int upper = end; // The index of the first element of the right part
  93.  
  94.             /*
  95.              * Partitioning with 2 pivots in case of different elements.
  96.              */
  97.             if (a[e1] < a[e2] && a[e2] < a[e3] && a[e3] < a[e4] && a[e4] < a[e5]) {
  98.  
  99.                 /*
  100.                  * Use the first and fifth of the five sorted elements as
  101.                  * the pivots. These values are inexpensive approximation
  102.                  * of tertiles. Note, that pivot1 < pivot2.
  103.                  */
  104.                 int pivot1 = a[e1];
  105.                 int pivot2 = a[e5];
  106.  
  107.                 /*
  108.                  * The first and the last elements to be sorted are moved
  109.                  * to the locations formerly occupied by the pivots. When
  110.                  * partitioning is completed, the pivots are swapped back
  111.                  * into their final positions, and excluded from the next
  112.                  * subsequent sorting.
  113.                  */
  114.                 a[e1] = a[lower];
  115.                 a[e5] = a[upper];
  116.  
  117.                 /*
  118.                  * Skip elements, which are less or greater than the pivots.
  119.                  */
  120.                 while (a[++lower] < pivot1);
  121.                 while (a[--upper] > pivot2);
  122.  
  123.                 /*
  124.                  * Backward 3-interval partitioning
  125.                  *
  126.                  *   left part                 central part          right part
  127.                  * +------------------------------------------------------------+
  128.                  * |  < pivot1  |   ?   |  pivot1 <= && <= pivot2  |  > pivot2  |
  129.                  * +------------------------------------------------------------+
  130.                  *             ^       ^                            ^
  131.                  *             |       |                            |
  132.                  *           lower     k                          upper
  133.                  *
  134.                  * Invariants:
  135.                  *
  136.                  *              all in (low, lower] < pivot1
  137.                  *    pivot1 <= all in (k, upper)  <= pivot2
  138.                  *              all in [upper, end) > pivot2
  139.                  *
  140.                  * Pointer k is the last index of ?-part
  141.                  */
  142.                 for (int unused = --lower, k = ++upper; --k > lower; ) {
  143.                     int ak = a[k];
  144.  
  145.                     if (ak < pivot1) { // Move a[k] to the left side
  146.                         while (lower < k) {
  147.                             if (a[++lower] >= pivot1) {
  148.                                 if (a[lower] > pivot2) {
  149.                                     a[k] = a[--upper];
  150.                                     a[upper] = a[lower];
  151.                                 } else {
  152.                                     a[k] = a[lower];
  153.                                 }
  154.                                 a[lower] = ak;
  155.                                 break;
  156.                             }
  157.                         }
  158.                     } else if (ak > pivot2) { // Move a[k] to the right side
  159.                         a[k] = a[--upper];
  160.                         a[upper] = ak;
  161.                     }
  162.                 }
  163.  
  164.                 /*
  165.                  * Swap the pivots into their final positions.
  166.                  */
  167.                 a[low] = a[lower]; a[lower] = pivot1;
  168.                 a[end] = a[upper]; a[upper] = pivot2;
  169.  
  170.                 /*
  171.                  * Sort non-left parts recursively (possibly in parallel),
  172.                  * excluding known pivots.
  173.                  */
  174.                 if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
  175.                     sorter.forkSorter(bits | 1, lower + 1, upper);
  176.                     sorter.forkSorter(bits | 1, upper + 1, high);
  177.                 } else {
  178.                     sort(sorter, a, bits | 1, lower + 1, upper);
  179.                     sort(sorter, a, bits | 1, upper + 1, high);
  180.                 }
  181.  
  182.             } else { // Use single pivot in case of many equal elements
  183.  
  184.                 /*
  185.                  * Use the third of the five sorted elements as the pivot.
  186.                  * This value is inexpensive approximation of the median.
  187.                  */
  188.                 int pivot = a[e3];
  189.  
  190.                 /*
  191.                  * The first element to be sorted is moved to the
  192.                  * location formerly occupied by the pivot. After
  193.                  * completion of partitioning the pivot is swapped
  194.                  * back into its final position, and excluded from
  195.                  * the next subsequent sorting.
  196.                  */
  197.                 a[e3] = a[lower];
  198.  
  199.                 /*
  200.                  * Traditional 3-way (Dutch National Flag) partitioning
  201.                  *
  202.                  *   left part                 central part    right part
  203.                  * +------------------------------------------------------+
  204.                  * |   < pivot   |     ?     |   == pivot   |   > pivot   |
  205.                  * +------------------------------------------------------+
  206.                  *              ^           ^                ^
  207.                  *              |           |                |
  208.                  *            lower         k              upper
  209.                  *
  210.                  * Invariants:
  211.                  *
  212.                  *   all in (low, lower] < pivot
  213.                  *   all in (k, upper)  == pivot
  214.                  *   all in [upper, end] > pivot
  215.                  *
  216.                  * Pointer k is the last index of ?-part
  217.                  */
  218.                 for (int k = ++upper; --k > lower; ) {
  219.                     int ak = a[k];
  220.  
  221.                     if (ak != pivot) {
  222.                         a[k] = pivot;
  223.  
  224.                         if (ak < pivot) { // Move a[k] to the left side
  225.                             while (a[++lower] < pivot);
  226.  
  227.                             if (a[lower] > pivot) {
  228.                                 a[--upper] = a[lower];
  229.                             }
  230.                             a[lower] = ak;
  231.                         } else { // ak > pivot - Move a[k] to the right side
  232.                             a[--upper] = ak;
  233.                         }
  234.                     }
  235.                 }
  236.  
  237.                 /*
  238.                  * Swap the pivot into its final position.
  239.                  */
  240.                 a[low] = a[lower]; a[lower] = pivot;
  241.  
  242.                 /*
  243.                  * Sort the right part (possibly in parallel), excluding
  244.                  * known pivot. All elements from the central part are
  245.                  * equal and therefore already sorted.
  246.                  */
  247.                 if (size > MIN_PARALLEL_SORT_SIZE && sorter != null) {
  248.                     sorter.forkSorter(bits | 1, upper, high);
  249.                 } else {
  250.                     sort(sorter, a, bits | 1, upper, high);
  251.                 }
  252.             }
  253.             high = lower; // Iterate along the left part
  254.         }
  255.     }
  256.  
  257.     /**
  258.      * Sorts the specified range of the array using mixed insertion sort.
  259.      *
  260.      * Mixed insertion sort is combination of simple insertion sort,
  261.      * pin insertion sort and pair insertion sort.
  262.      *
  263.      * In the context of Dual-Pivot Quicksort, the pivot element
  264.      * from the left part plays the role of sentinel, because it
  265.      * is less than any elements from the given part. Therefore,
  266.      * expensive check of the left range can be skipped on each
  267.      * iteration unless it is the leftmost call.
  268.      *
  269.      * @param a the array to be sorted
  270.      * @param low the index of the first element, inclusive, to be sorted
  271.      * @param end the index of the last element for simple insertion sort
  272.      * @param high the index of the last element, exclusive, to be sorted
  273.      */
  274.     private static void mixedInsertionSort(int[] a, int low, int end, int high) {
  275.         if (end == high) {
  276.  
  277.             /*
  278.              * Invoke simple insertion sort on tiny array.
  279.              */
  280.             for (int i; ++low < end; ) {
  281.                 int ai = a[i = low];
  282.  
  283.                 while (ai < a[--i]) {
  284.                     a[i + 1] = a[i];
  285.                 }
  286.                 a[i + 1] = ai;
  287.             }
  288.         } else {
  289.  
  290.             /*
  291.              * Start with pin insertion sort on small part.
  292.              *
  293.              * Pin insertion sort is extended simple insertion sort.
  294.              * The main idea of this sort is to put elements larger
  295.              * than an element called pin to the end of array (the
  296.              * proper area for such elements). It avoids expensive
  297.              * movements of these elements through the whole array.
  298.              */
  299.             int pin = a[end];
  300.  
  301.             for (int i, p = high; ++low < end; ) {
  302.                 int ai = a[i = low];
  303.  
  304.                 if (ai < a[i - 1]) { // Small element
  305.  
  306.                     /*
  307.                      * Insert small element into sorted part.
  308.                      */
  309.                     a[i] = a[--i];
  310.  
  311.                     while (ai < a[--i]) {
  312.                         a[i + 1] = a[i];
  313.                     }
  314.                     a[i + 1] = ai;
  315.  
  316.                 } else if (p > i && ai > pin) { // Large element
  317.  
  318.                     /*
  319.                      * Find element smaller than pin.
  320.                      */
  321.                     while (a[--p] > pin);
  322.  
  323.                     /*
  324.                      * Swap it with large element.
  325.                      */
  326.                     if (p > i) {
  327.                         ai = a[p];
  328.                         a[p] = a[i];
  329.                     }
  330.  
  331.                     /*
  332.                      * Insert small element into sorted part.
  333.                      */
  334.                     while (ai < a[--i]) {
  335.                         a[i + 1] = a[i];
  336.                     }
  337.                     a[i + 1] = ai;
  338.                 }
  339.             }
  340.  
  341.             /*
  342.              * Continue with pair insertion sort on remain part.
  343.              */
  344.             for (int i; low < high; ++low) {
  345.                 int a1 = a[i = low], a2 = a[++low];
  346.  
  347.                 /*
  348.                  * Insert two elements per iteration: at first, insert the
  349.                  * larger element and then insert the smaller element, but
  350.                  * from the position where the larger element was inserted.
  351.                  */
  352.                 if (a1 > a2) {
  353.  
  354.                     while (a1 < a[--i]) {
  355.                         a[i + 2] = a[i];
  356.                     }
  357.                     a[++i + 1] = a1;
  358.  
  359.                     while (a2 < a[--i]) {
  360.                         a[i + 1] = a[i];
  361.                     }
  362.                     a[i + 1] = a2;
  363.  
  364.                 } else if (a1 < a[i - 1]) {
  365.  
  366.                     while (a2 < a[--i]) {
  367.                         a[i + 2] = a[i];
  368.                     }
  369.                     a[++i + 1] = a2;
  370.  
  371.                     while (a1 < a[--i]) {
  372.                         a[i + 1] = a[i];
  373.                     }
  374.                     a[i + 1] = a1;
  375.                 }
  376.             }
  377.         }
  378.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement