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 }
    
    
  • 相关阅读:
    Elasticsearch布尔查询——bool
    Elasticsearch查询
    数据从文件导入Elasticsearch
    Elasticsearch批处理操作——bulk API
    Mysql笔记——DCL
    Mysql笔记——DML
    Mysql笔记——DDL
    Java笔记——面向接口编程(DAO模式)
    Java笔记——equals和==的区别
    JavaWeb笔记——注册登录系统项目思路
  • 原文地址:https://www.cnblogs.com/william-cheung/p/8893608.html
Copyright © 2011-2022 走看看