上一篇提到,快速排序的平均时间复杂度是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     }
Randomized quicksort

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 }
RandomizedQuickSort.java
 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 }
CommonUtils.java