上一篇提到,快速排序的平均时间复杂度是O(nlgn),比其他相同时间复杂度的堆排序、归并排序都要快,但这是有前提的,就是假定要排序的序列是随机分布的,而不是有序的。实际上,对于已经排好的序列,如果用快速排序时间复杂度是O(n2)。为应对这样的有序序列,于是出现了本篇要讲的随机化快速排序(Randomized quicksort)。
快速排序在选主元(pivot)时,总是选择第一个;随机化快速排序的思想是,随机从序列中选择一个作为主元。
(一)算法实现
1 protected void quicksort(int[] array, int first, int last) { 2 int randomIndex = CommonUtils.getRandomInt(first, last); 3 CommonUtils.swap(array, first, randomIndex); 4 5 int pivot = array[first]; 6 int i = first; 7 int j = last - 1; 8 boolean serachBig = true; 9 while (i < j) { 10 if (serachBig) { 11 if (array[j] < pivot) { 12 array[i] = array[j]; 13 i++; 14 serachBig = false; 15 } else { 16 j--; 17 } 18 } else { 19 if (array[i] > pivot) { 20 array[j] = array[i]; 21 j--; 22 serachBig = true; 23 } else { 24 i++; 25 } 26 } 27 } 28 array[i] = pivot; 29 30 if (i - first > 1) { 31 quicksort(array, first, i); 32 } 33 if (last - i > 2) { 34 quicksort(array, i + 1, last); 35 } 36 }
1)对于任何输入序列,随机化快速排序的时间复杂度是O(nlgn)
2)考虑递归,随机化快速排序空间复杂度是O(logn),不是原地排序
3)随机化快速排序属于比较排序
4)随机化快速排序不是稳定排序算法
(二)仿真结果
下面比较快速排序和随机化快速排序,分别对随机序列和有序序列排序。
**************************************************
Number to Sort is:2500
Randomized sequence to sort is:{741988,773994,855169,757518,82329,596105,876316,561224,928992,721115...}
Cost time of 【QuickSort】 is(milliseconds):0
Sort result of 【QuickSort】:{250,786,1209,1434,2306,3074,3715,3800,4669,5510...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):1
Sort result of 【RandomizedQuickSort】:{250,786,1209,1434,2306,3074,3715,3800,4669,5510...}
Ordered sequence to sort is:{250,786,1209,1434,2306,3074,3715,3800,4669,5510...}
Cost time of 【QuickSort】 is(milliseconds):6
Sort result of 【QuickSort】:{250,786,1209,1434,2306,3074,3715,3800,4669,5510...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):0
Sort result of 【RandomizedQuickSort】:{250,786,1209,1434,2306,3074,3715,3800,4669,5510...}
**************************************************
Number to Sort is:25000
Randomized sequence to sort is:{791264,308128,451250,42835,620880,820510,650527,51751,716592,292370...}
Cost time of 【QuickSort】 is(milliseconds):2
Sort result of 【QuickSort】:{52,82,148,166,180,182,232,354,382,394...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):3
Sort result of 【RandomizedQuickSort】:{52,82,148,166,180,182,232,354,382,394...}
Ordered sequence to sort is:{52,82,148,166,180,182,232,354,382,394...}
Cost time of 【QuickSort】 is(milliseconds):650
Sort result of 【QuickSort】:{52,82,148,166,180,182,232,354,382,394...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):2
Sort result of 【RandomizedQuickSort】:{52,82,148,166,180,182,232,354,382,394...}
**************************************************
Number to Sort is:250000
Randomized sequence to sort is:{595090,163678,171858,249808,15138,951048,53215,611066,766255,454662...}
Cost time of 【QuickSort】 is(milliseconds):30
Sort result of 【QuickSort】:{1,1,8,8,10,11,11,17,31,32...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):55
Sort result of 【RandomizedQuickSort】:{1,1,8,8,10,11,11,17,31,32...}
Ordered sequence to sort is:{1,1,8,8,10,11,11,17,31,32...}
Cost time of 【QuickSort】 is(milliseconds):54,886
Sort result of 【QuickSort】:{1,1,8,8,10,11,11,17,31,32...}
Cost time of 【RandomizedQuickSort】 is(milliseconds):19
Sort result of 【RandomizedQuickSort】:{1,1,8,8,10,11,11,17,31,32...}
相关代码:
1 package com.cnblogs.riyueshiwang.sort; 2 3 import java.util.Arrays; 4 5 public class RandomizedQuickSort extends abstractSort { 6 @Override 7 protected void sort(int[] toSort) { 8 quicksort(toSort, 0, toSort.length); 9 } 10 11 protected void quicksort(int[] array, int first, int last) { 12 int randomIndex = CommonUtils.getRandomInt(first, last); 13 CommonUtils.swap(array, first, randomIndex); 14 15 int pivot = array[first]; 16 int i = first; 17 int j = last - 1; 18 boolean serachBig = true; 19 while (i < j) { 20 if (serachBig) { 21 if (array[j] < pivot) { 22 array[i] = array[j]; 23 i++; 24 serachBig = false; 25 } else { 26 j--; 27 } 28 } else { 29 if (array[i] > pivot) { 30 array[j] = array[i]; 31 j--; 32 serachBig = true; 33 } else { 34 i++; 35 } 36 } 37 } 38 array[i] = pivot; 39 40 if (i - first > 1) { 41 quicksort(array, first, i); 42 } 43 if (last - i > 2) { 44 quicksort(array, i + 1, last); 45 } 46 } 47 48 public static void main(String[] args) { 49 for (int j = 0, n = 2500; j < 3; j++, n = n * 10) { 50 System.out 51 .println("**************************************************"); 52 System.out.println("Number to Sort is:" + n); 53 int[] array = CommonUtils.getRandomIntArray(n, 1000000); 54 55 System.out.print("Randomized sequence to sort is:"); 56 CommonUtils.printIntArray(array); 57 58 int[] array1 = Arrays.copyOf(array, n); 59 new QuickSort().sortAndprint(array1); 60 int[] array2 = Arrays.copyOf(array, n); 61 new RandomizedQuickSort().sortAndprint(array2); 62 63 System.out.print("Ordered sequence to sort is:"); 64 CommonUtils.printIntArray(array1); 65 new QuickSort().sortAndprint(array1); 66 new RandomizedQuickSort().sortAndprint(array1); 67 68 } 69 70 } 71 }
1 package com.cnblogs.riyueshiwang.sort; 2 3 import java.util.Random; 4 5 public class CommonUtils { 6 private static Random random = new Random(); 7 8 public static void printIntArray(int[] array) { 9 System.out.print('{'); 10 11 int length = Math.min(array.length, 10); 12 for (int i = 0; i < length; i++) { 13 System.out.print(array[i]); 14 if (i != length - 1) { 15 System.out.print(','); 16 } else { 17 if (array.length > 10) { 18 System.out.print("..."); 19 } 20 System.out.println('}'); 21 } 22 } 23 } 24 25 public static int[] getRandomIntArray(int size, int maxValue) { 26 int[] array = new int[size]; 27 for (int i = 0; i < size; i++) { 28 array[i] = random.nextInt(maxValue); 29 } 30 return array; 31 } 32 33 public static void swap(int[] toSort, int i, int j) { 34 int temp = toSort[i]; 35 toSort[i] = toSort[j]; 36 toSort[j] = temp; 37 } 38 39 /** 40 * 41 * @param first 42 * begin value 43 * @param last 44 * end value 45 * @return a pseudo random, uniformly distributed int value between first 46 * (inclusive) and last (exclusive) 47 * 48 */ 49 public static int getRandomInt(int first, int last) { 50 return random.nextInt(last - first) + first; 51 } 52 }