zoukankan      html  css  js  c++  java
  • Partial QuickSort in Java

    The Partial QuickSort algorithm was first introduced by Conrado Martínez in his paper "Partial QuickSort".

    Partial QuickSort works as follows. Like quicksort but in every recursive call we receive a subarray a[i..j] and a k that k >= i. We want to rearrange the subarray so that a[i..k] contains the k - i + 1 smallest elements of a[i, j] in ascending order; if k > j that means we must fully sort a[i..j].

    Pseudo code:
    function partial_quicksort(a, i, j, k)
        if i < j
            p ← partition(a, i, j)
            partial_quicksort(a, i, p-1, k)
            if p < k-1
                partial_quicksort(a, p+1, j, k)
     
    The expected running time of this algorithm is only O(n + m log m) where n is the size of the subarray a[i..j] and m is the number of smallest elements we need

    Java Code:
      1 import java.util.Comparator;
      2 import java.util.Random;
      3 
      4 /**
      5  * Created by william on 08/04/2018.
      6  */
      7 public class QuickSort<T> {
      8 
      9     private static final int MAX_STACK_SIZE = 64;
     10     private static final int MAX_ARRAY_SIZE;
     11     static {
     12         long maxArraySize = 1L << (MAX_STACK_SIZE / 2 - 1);
     13         MAX_ARRAY_SIZE = (int) Math.min(
     14                 maxArraySize, (long) Integer.MAX_VALUE);
     15     }
     16 
     17     private static final int INSERTION_SORT_THRESHOLD = 16;
     18 
     19     private static final int MEDIAN_OF_THREE_THRESHOLD = 32;
     20     
     21     public static <T> void partialSort(
     22             T[] a, int fromIndex, int toIndex, int middleIndex,
     23             Comparator<? super T> c) {
     24         rangeCheck(a.length, fromIndex, toIndex);
     25 
     26         int[] stack = new int[MAX_STACK_SIZE];
     27         int top = 0;
     28 
     29         stack[top++] = fromIndex;
     30         stack[top++] = toIndex;
     31 
     32         while (top > 0) {
     33             toIndex = stack[--top];
     34             fromIndex = stack[--top];
     35 
     36             if (toIndex - fromIndex <= INSERTION_SORT_THRESHOLD) {
     37                 for (int i = fromIndex + 1; i < toIndex; i++) {
     38                     T x = a[i];
     39                     int j = i;
     40                     while (--j >= fromIndex && c.compare(x, a[j]) < 0) {
     41                         a[j + 1] = a[j];
     42                     }
     43                     a[j + 1] = x;
     44                 }
     45                 continue;
     46             }
     47 
     48             int pivotIndex = partition(a, fromIndex, toIndex, c);
     49 
     50             if (pivotIndex - fromIndex >= toIndex - pivotIndex - 1) {
     51                 stack[top++] = fromIndex;
     52                 stack[top++] = pivotIndex;
     53 
     54                 if (pivotIndex < middleIndex - 1) {
     55                     stack[top++] = pivotIndex + 1;
     56                     stack[top++] = toIndex;
     57                 }
     58             } else {
     59                 if (pivotIndex < middleIndex - 1) {
     60                     stack[top++] = pivotIndex + 1;
     61                     stack[top++] = toIndex;
     62                 }
     63                 if (pivotIndex > fromIndex) {
     64                     stack[top++] = fromIndex;
     65                     stack[top++] = pivotIndex;
     66                 }
     67             }
     68         }
     69     }
     70 
     71     private static void rangeCheck(
     72             int arrayLength, int fromIndex, int toIndex) {
     73 
     74         if (arrayLength > MAX_ARRAY_SIZE) {
     75             throw new IllegalArgumentException("size of array (" +
     76                     arrayLength + ") is too large, maximum array " +
     77                     "size allowed: " + MAX_ARRAY_SIZE);
     78         }
     79 
     80         if (fromIndex < 0) {
     81             throw new ArrayIndexOutOfBoundsException(fromIndex);
     82         }
     83 
     84         if (toIndex > arrayLength) {
     85             throw new ArrayIndexOutOfBoundsException(toIndex);
     86         }
     87 
     88         if (fromIndex > toIndex) {
     89             throw new IllegalArgumentException(
     90                     "fromIndex(" + fromIndex + ") > " +
     91                             "toIndex(" + toIndex + ")");
     92         }
     93     }
     94 
     95     private static final long RANDOM_SEED = System.currentTimeMillis();
     96 
     97     private static <T> int partition(T[] a, int fromIndex, int toIndex,
     98                                      Comparator<? super T> c) {
     99         int n = toIndex - fromIndex;
    100         int pivotIndex = fromIndex + (n >> 1);
    101         if (n > MEDIAN_OF_THREE_THRESHOLD) {
    102             Random random = new Random(RANDOM_SEED);
    103             pivotIndex = medianOfThree(a,
    104                     fromIndex + random.nextInt(n),
    105                     fromIndex + random.nextInt(n),
    106                     fromIndex + random.nextInt(n),
    107                     c);
    108         }
    109         swap(a, fromIndex, pivotIndex);
    110 
    111         T pivot = a[fromIndex];
    112         int i = fromIndex;
    113         for (int j = fromIndex + 1; j < toIndex; j++) {
    114             if (c.compare(a[j], pivot) < 0) {
    115                 swap(a, ++i, j);
    116             }
    117         }
    118         swap(a, fromIndex, i);
    119         return i;
    120     }
    121 
    122     private static <T> int medianOfThree(T[] a, int i, int j, int k,
    123                                          Comparator<? super T> c) {
    124         return c.compare(a[i], a[j]) < 0 ?
    125                 (c.compare(a[j], a[k]) < 0 ? j :
    126                         c.compare(a[i], a[k]) < 0 ? k : i) :
    127                 (c.compare(a[k], a[j]) < 0 ? j :
    128                         c.compare(a[i], a[k]) < 0 ? i : k);
    129     }
    130 
    131     private static <T> void swap(T[] a, int i, int j) {
    132         T temp = a[i];
    133         a[i] = a[j];
    134         a[j] = temp;
    135     }
    136 
    137     public static <T> void sort(T[] a, Comparator<? super T> c) {
    138         sort(a, 0, a.length, c);
    139     }
    140 
    141     public static <T> void sort(T[] a, int fromIndex, int toIndex,
    142                                 Comparator<? super T> c) {
    143         partialSort(a, fromIndex, toIndex, toIndex, c);
    144     }
    145 
    146     public static <T> void partialSort(T[] a, int k,
    147                                        Comparator<? super T> c) {
    148         partialSort(a, 0, a.length, k, c);
    149     }
    150 }
    
    
  • 相关阅读:
    数据结构实验之排序八:快速排序-sdut
    青蛙过河-sdut
    汉诺塔系列2-sdut
    汉诺塔-sdut
    Fighting_小银考呀考不过四级-sdut
    【JS】只能输入数字和两位小数的JS
    jQuery form 表达验证
    JS正则表达式验证数字非常全
    在lua中优雅的操作日期和时间
    lua 判断为空的逻辑
  • 原文地址:https://www.cnblogs.com/william-cheung/p/8893608.html
Copyright © 2011-2022 走看看