Advertisement
osipyonok

anti quick sort

Jun 19th, 2017
780
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.75 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4.  
  5. class Anti_QSort implements Runnable {
  6.  
  7.     private final Random rnd = new Random(239);
  8.  
  9.     private final int INSERTION_SORT_THRESHOLD = 47;
  10.  
  11.     private int MIN_VALUE;
  12.     private int MAX_VALUE;
  13.     private final int NO_VALUE = -1;
  14.  
  15.     private void hackedSort(int[] a, int[] p, int left, int right, boolean leftmost) {
  16.         int length = right - left + 1;
  17.  
  18.         // Use insertion sort on tiny arrays
  19.         if (length < INSERTION_SORT_THRESHOLD) {
  20.             for (int i = right; i >= left; i--) {
  21.                 if (a[i] == NO_VALUE) a[i] = MIN_VALUE++;
  22.             }
  23.             randomShuffle(a, left, right); // why not?
  24.  
  25.             if (leftmost) {
  26.                 for (int i = left, j = i; i < right; j = ++i) {
  27.                     int ai = a[i + 1];
  28.                     int pi = p[i + 1];
  29.                     while (ai < a[j]) {
  30.                         a[j + 1] = a[j];
  31.                         p[j + 1] = p[j];
  32.                         if (j-- == left) {
  33.                             break;
  34.                         }
  35.                     }
  36.                     a[j + 1] = ai;
  37.                     p[j + 1] = pi;
  38.                 }
  39.             } else {
  40.                 /*
  41.                  * Skip the longest ascending sequence.
  42.                  */
  43.                 do {
  44.                     if (left >= right) {
  45.                         return;
  46.                     }
  47.                 } while (a[++left] >= a[left - 1]);
  48.  
  49.                 for (int k = left; ++left <= right; k = ++left) {
  50.                     int a1 = a[k], a2 = a[left];
  51.                     int p1 = p[k], p2 = p[left];
  52.  
  53.                     if (a1 < a2) {
  54.                         a2 = a1; a1 = a[left];
  55.                         p2 = p1; p1 = p[left];
  56.                     }
  57.                     while (a1 < a[--k]) {
  58.                         a[k + 2] = a[k];
  59.                         p[k + 2] = p[k];
  60.                     }
  61.                     ++k;
  62.                     a[k + 1] = a1;
  63.                     p[k + 1] = p1;
  64.  
  65.                     while (a2 < a[--k]) {
  66.                         a[k + 1] = a[k];
  67.                         p[k + 1] = p[k];
  68.                     }
  69.                     a[k + 1] = a2;
  70.                     p[k + 1] = p2;
  71.                 }
  72.                 int last = a[right];
  73.                 int plast = p[right];
  74.  
  75.                 while (last < a[--right]) {
  76.                     a[right + 1] = a[right];
  77.                     p[right + 1] = p[right];
  78.                 }
  79.                 a[right + 1] = last;
  80.                 p[right + 1] = plast;
  81.             }
  82.             return;
  83.         }
  84.  
  85.         // Inexpensive approximation of length / 7
  86.         int seventh = (length >> 3) + (length >> 6) + 1;
  87.  
  88.         int e3 = (left + right) >>> 1; // The midpoint
  89.         int e2 = e3 - seventh;
  90.         int e1 = e2 - seventh;
  91.         int e4 = e3 + seventh;
  92.         int e5 = e4 + seventh;
  93.  
  94.         if (a[e5] == NO_VALUE) a[e5] = MIN_VALUE++;
  95.         if (a[e4] == NO_VALUE) a[e4] = MIN_VALUE++;
  96.  
  97.         if (a[e1] == NO_VALUE) a[e1] = MAX_VALUE--;
  98.         if (a[e2] == NO_VALUE) a[e2] = MAX_VALUE--;
  99.  
  100.         // Sort these elements using insertion sort
  101.         if (less(a[e2], a[e1])) { int t = a[e2]; a[e2] = a[e1]; a[e1] = t;
  102.             int s = p[e2]; p[e2] = p[e1]; p[e1] = s; }
  103.  
  104.         if (less(a[e3], a[e2])) { int t = a[e3]; a[e3] = a[e2]; a[e2] = t;
  105.             int s = p[e3]; p[e3] = p[e2]; p[e2] = s;
  106.             if (less(t, a[e1])) { a[e2] = a[e1]; a[e1] = t;
  107.                 p[e2] = p[e1]; p[e1] = s; }
  108.         }
  109.         if (less(a[e4], a[e3])) { int t = a[e4]; a[e4] = a[e3]; a[e3] = t;
  110.             int s = p[e4]; p[e4] = p[e3]; p[e3] = s;
  111.             if (less(t, a[e2])) { a[e3] = a[e2]; a[e2] = t;
  112.                 p[e3] = p[e2]; p[e2] = s;
  113.                 if (less(t, a[e1])) { a[e2] = a[e1]; a[e1] = t;
  114.                     p[e2] = p[e1]; p[e1] = s; }
  115.             }
  116.         }
  117.         if (less(a[e5], a[e4])) { int t = a[e5]; a[e5] = a[e4]; a[e4] = t;
  118.             int s = p[e5]; p[e5] = p[e4]; p[e4] = s;
  119.             if (less(t, a[e3])) { a[e4] = a[e3]; a[e3] = t;
  120.                 p[e4] = p[e3]; p[e3] = s;
  121.                 if (less(t, a[e2])) { a[e3] = a[e2]; a[e2] = t;
  122.                     p[e3] = p[e2]; p[e2] = s;
  123.                     if (less(t, a[e1])) { a[e2] = a[e1]; a[e1] = t;
  124.                         p[e2] = p[e1]; p[e1] = s; }
  125.                 }
  126.             }
  127.         }
  128.  
  129.         // Pointers
  130.         int less  = left;  // The index of the first element of center part
  131.         int great = right; // The index before the first element of right part
  132.  
  133.         if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
  134.             /*
  135.              * Use the second and fourth of the five sorted elements as pivots.
  136.              * These values are inexpensive approximations of the first and
  137.              * second terciles of the array. Note that pivot1 <= pivot2.
  138.              */
  139.             int pivot1 = a[e2];
  140.             int pivot2 = a[e4];
  141.             int ppivot1 = p[e2];
  142.             int ppivot2 = p[e4];
  143.  
  144.             /*
  145.              * The first and the last elements to be sorted are moved to the
  146.              * locations formerly occupied by the pivots. When partitioning
  147.              * is complete, the pivots are swapped back into their final
  148.              * positions, and excluded from subsequent sorting.
  149.              */
  150.             a[e2] = a[left];
  151.             a[e4] = a[right];
  152.             p[e2] = p[left];
  153.             p[e4] = p[right];
  154.  
  155.             /*
  156.              * Skip elements, which are less or greater than pivot values.
  157.              */
  158.             //while (a[++less] < pivot1);
  159.             //while (a[--great] > pivot2);
  160.             while (less(a[++less], pivot1));
  161.             while (greater(a[--great], pivot2));
  162.  
  163.             /*
  164.              * Partitioning:
  165.              *
  166.              *   left part           center part                   right part
  167.              * +--------------------------------------------------------------+
  168.              * |  < pivot1  |  pivot1 <= && <= pivot2  |    ?    |  > pivot2  |
  169.              * +--------------------------------------------------------------+
  170.              *               ^                          ^       ^
  171.              *               |                          |       |
  172.              *              less                        k     great
  173.              *
  174.              * Invariants:
  175.              *
  176.              *              all in (left, less)   < pivot1
  177.              *    pivot1 <= all in [less, k)     <= pivot2
  178.              *              all in (great, right) > pivot2
  179.              *
  180.              * Pointer k is the first index of ?-part.
  181.              */
  182.             outer:
  183.             for (int k = less - 1; ++k <= great; ) {
  184.                 int ak = a[k];
  185.                 int pk = p[k];
  186.                 //if (ak < pivot1) { // Move a[k] to left part
  187.                 if (less(ak, pivot1)) { // Move a[k] to left part
  188.                     a[k] = a[less];
  189.                     p[k] = p[less];
  190.                     /*
  191.                      * Here and below we use "a[i] = b; i++;" instead
  192.                      * of "a[i++] = b;" due to performance issue.
  193.                      */
  194.                     a[less] = ak;
  195.                     p[less] = pk;
  196.                     ++less;
  197.                     //} else if (ak > pivot2) { // Move a[k] to right part
  198.                 } else if (greater(ak, pivot2)) { // Move a[k] to right part
  199.                     //while (a[great] > pivot2) {
  200.                     while (greater(a[great], pivot2)) {
  201.                         if (great-- == k) {
  202.                             break outer;
  203.                         }
  204.                     }
  205.                     //if (a[great] < pivot1) { // a[great] <= pivot2
  206.                     if (less(a[great], pivot1)) { // a[great] <= pivot2
  207.                         a[k] = a[less];
  208.                         p[k] = p[less];
  209.                         a[less] = a[great];
  210.                         p[less] = p[great];
  211.                         ++less;
  212.                     } else { // pivot1 <= a[great] <= pivot2
  213.                         a[k] = a[great];
  214.                         p[k] = p[great];
  215.                     }
  216.                     /*
  217.                      * Here and below we use "a[i] = b; i--;" instead
  218.                      * of "a[i--] = b;" due to performance issue.
  219.                      */
  220.                     a[great] = ak;
  221.                     p[great] = pk;
  222.                     --great;
  223.                 }
  224.             }
  225.  
  226.             // Swap pivots into their final positions
  227.             a[left]  = a[less  - 1]; a[less  - 1] = pivot1;
  228.             a[right] = a[great + 1]; a[great + 1] = pivot2;
  229.             p[left]  = p[less  - 1]; p[less  - 1] = ppivot1;
  230.             p[right] = p[great + 1]; p[great + 1] = ppivot2;
  231.  
  232.  
  233.             // Sort left and right parts recursively, excluding known pivots
  234.             hackedSort(a, p, left, less - 2, leftmost);
  235.             hackedSort(a, p, great + 2, right, false);
  236.  
  237.             /*
  238.              * If center part is too large (comprises > 4/7 of the array),
  239.              * swap internal pivot values to ends.
  240.              */
  241.             if (less < e1 && e5 < great) {
  242.                 /*
  243.                  * Skip elements, which are equal to pivot values.
  244.                  */
  245.                 while (a[less] == pivot1) {
  246.                     throw new RuntimeException("We should not enter here!");
  247. //                    ++less;
  248.                 }
  249.  
  250.                 while (a[great] == pivot2) {
  251.                     throw new RuntimeException("We should not enter here!");
  252. //                    --great;
  253.                 }
  254.  
  255.                 /*
  256.                  * Partitioning:
  257.                  *
  258.                  *   left part         center part                  right part
  259.                  * +----------------------------------------------------------+
  260.                  * | == pivot1 |  pivot1 < && < pivot2  |    ?    | == pivot2 |
  261.                  * +----------------------------------------------------------+
  262.                  *              ^                        ^       ^
  263.                  *              |                        |       |
  264.                  *             less                      k     great
  265.                  *
  266.                  * Invariants:
  267.                  *
  268.                  *              all in (*,  less) == pivot1
  269.                  *     pivot1 < all in [less,  k)  < pivot2
  270.                  *              all in (great, *) == pivot2
  271.                  *
  272.                  * Pointer k is the first index of ?-part.
  273.                  */
  274.                 outer:
  275.                 for (int k = less - 1; ++k <= great; ) {
  276.                     int ak = a[k];
  277.                     int pk = p[k];
  278.                     if (ak == pivot1) { // Move a[k] to left part
  279.                         a[k] = a[less];
  280.                         p[k] = p[less];
  281.                         a[less] = ak;
  282.                         p[less] = pk;
  283.                         ++less;
  284.                     } else if (ak == pivot2) { // Move a[k] to right part
  285.                         while (a[great] == pivot2) {
  286.                             if (great-- == k) {
  287.                                 break outer;
  288.                             }
  289.                         }
  290.                         if (a[great] == pivot1) { // a[great] < pivot2
  291.                             a[k] = a[less];
  292.                             p[k] = p[less];
  293.                             /*
  294.                              * Even though a[great] equals to pivot1, the
  295.                              * assignment a[less] = pivot1 may be incorrect,
  296.                              * if a[great] and pivot1 are floating-point zeros
  297.                              * of different signs. Therefore in float and
  298.                              * double sorting methods we have to use more
  299.                              * accurate assignment a[less] = a[great].
  300.                              */
  301.                             a[less] = pivot1;
  302.                             p[less] = ppivot1;
  303.                             ++less;
  304.                         } else { // pivot1 < a[great] < pivot2
  305.                             a[k] = a[great];
  306.                             p[k] = p[great];
  307.                         }
  308.                         a[great] = ak;
  309.                         p[great] = pk;
  310.                         --great;
  311.                     }
  312.                 }
  313.             }
  314.  
  315.             // Sort center part recursively
  316.             hackedSort(a, p, less, great, false);
  317.  
  318.         } else { // Partitioning with one pivot
  319.             throw new RuntimeException("We should not enter here!");
  320.  
  321.         }
  322.     }
  323.  
  324.     private void randomShuffle(int[] a, int left, int right) {
  325.         for (int i = left; i <= right; i++) {
  326.             int j = left + rnd.nextInt(i - left + 1);
  327.             swap(a, i, j);
  328.         }
  329.     }
  330.  
  331.     private void swap(int[] a, int i, int j) {
  332.         int t = a[i];
  333.         a[i] = a[j];
  334.         a[j] = t;
  335.     }
  336.  
  337.     private boolean less(int a, int b) {
  338.         if (a != NO_VALUE && b != NO_VALUE) {
  339.             return a < b;
  340.         }
  341.         if (a == NO_VALUE) {
  342.             return b > MAX_VALUE;
  343.         }
  344.         if (b == NO_VALUE) {
  345.             return a < MIN_VALUE;
  346.         }
  347.         throw new RuntimeException("We should not enter here!");
  348.     }
  349.  
  350.     private boolean greater(int a, int b) {
  351.         if (a != NO_VALUE && b != NO_VALUE) {
  352.             return a > b;
  353.         }
  354.         if (a == NO_VALUE) {
  355.             return b < MIN_VALUE;
  356.         }
  357.         if (b == NO_VALUE) {
  358.             return a > MAX_VALUE;
  359.         }
  360.         throw new RuntimeException("We should not enter here!");
  361.     }
  362.  
  363.     int n;
  364.  
  365.     public Anti_QSort(int n) {
  366.         this.n = n;
  367.     }
  368.  
  369.     public void run() {
  370.         int[] a = new int[n];
  371.         int[] p = new int[n];
  372.  
  373.         for (int i = 0; i < n; i++) {
  374.             a[i] = NO_VALUE;
  375.             p[i] = i;
  376.         }
  377.         MIN_VALUE = 1;
  378.         MAX_VALUE = n;
  379.  
  380.         long t1, t2;
  381.  
  382.         t1 = System.currentTimeMillis();
  383.         hackedSort(a, p, 0, n-1, true);
  384.         t2 = System.currentTimeMillis();
  385. //        System.out.println("Generation time = " + (t2 - t1) + " ms.");
  386.  
  387.         checkValues(a, 1, n);
  388.         checkValues(p, 0, n-1);
  389.  
  390.         applyPermutation(a, p);
  391.  
  392.   //      t1 = System.currentTimeMillis();
  393.  //       Arrays.sort(a.clone());
  394. //        t2 = System.currentTimeMillis();
  395.   //      System.out.println("Sorting time = " + (t2 - t1) + " ms.");
  396.  
  397. //        /*
  398.         printArray(a, new PrintWriter(System.out));
  399. //        */
  400.  
  401.  /*       t1 = System.currentTimeMillis();
  402.         Arrays.sort(a.clone());
  403.         t2 = System.currentTimeMillis();
  404.         System.out.println("Sorting time = " + (t2 - t1) + " ms.");*/
  405.     }
  406.  
  407.     private void applyPermutation(int[] a, int[] pos) {
  408.         int n = a.length;
  409.         int[] tmp = new int[n];
  410.         for (int i = 0; i < n; i++) {
  411.             tmp[pos[i]] = a[i];
  412.         }
  413.         for (int i = 0; i < n; i++) {
  414.             a[i] = tmp[i];
  415.             pos[i] = i;
  416.         }
  417.     }
  418.  
  419.     private void checkValues(int[] a, int min, int max) {
  420.         boolean[] b = new boolean[max - min + 1];
  421.         for (int x : a) {
  422.             if (b[x - min]) {
  423.                 throw new RuntimeException();
  424.             }
  425.             b[x - min] = true;
  426.         }
  427.     }
  428.  
  429.     private void printArray(int[] a, PrintWriter pw) {
  430.         int n = a.length;
  431.         pw.println(n);
  432.         for (int i = 0; i < n; i++) {
  433.             pw.print(a[i]);
  434.             if (i == n-1) pw.println(); else pw.print(' ');
  435.         }
  436.         pw.close();
  437.     }
  438.  
  439.  
  440.     public static void main(String[] args) {
  441.         new Thread(null, new Anti_QSort(100000), "", 128*1024*1024).start();
  442.     }
  443.  
  444. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement