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 }
    
    
  • 相关阅读:
    笔记本连接蓝牙音箱声音异常
    fence安装中遇到的问题
    ssm整合关键
    第二章:数字系统
    第一章:计算器系统体系结构
    第二章:变量和基本类型
    第一章:开始
    第十九章:特殊工具与技术
    第十八章: 用于大型程序的工具
    第十七章:标准库特殊设施
  • 原文地址:https://www.cnblogs.com/william-cheung/p/8893608.html
Copyright © 2011-2022 走看看