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 }
    
    
  • 相关阅读:
    用XYNTService把Python程序变为服务
    今天被坑了,而且被坑的好爽! 该死的UTF-8 有 BOM 格式编码
    php 图片上传 500 Internal Server Error 错误
    Linux下 PHP 安装pecl_http方法
    PHP压缩html网页代码原理(清除空格,换行符,制表符,注释标记)
    一段代码让DedeCMS完美兼容PHP5.4
    win7+ oracle +php环境的搭建
    在netbeans下使用调试PHP的插件XdeBug
    使用webbench做压力测试
    ubuntu 13.04 nginx.conf 配置详解
  • 原文地址:https://www.cnblogs.com/william-cheung/p/8893608.html
Copyright © 2011-2022 走看看