|
19 | 19 | #define __QUICKSORT_H__
|
20 | 20 |
|
21 | 21 | #include <generic.h>
|
| 22 | +#include <cassert> |
22 | 23 |
|
23 | 24 | namespace alg {
|
| 25 | + |
| 26 | + /** |
| 27 | + * Return median of begin, middle, and end. |
| 28 | + * Order these and hide the pivot. |
| 29 | + */ |
| 30 | + template<typename T> |
| 31 | + static const T & __median3(T list[], int begin, int end) { |
| 32 | + assert(begin + 2 <= end); |
| 33 | + int middle = end - (end - begin) / 2; |
| 34 | + if (list[middle] < list[begin]) |
| 35 | + swap(list[middle], list[begin]); |
| 36 | + if (list[end] < list[begin]) |
| 37 | + swap(list[end], list[begin]); |
| 38 | + if (list[end] < list[middle]) |
| 39 | + swap(list[end], list[middle]); |
| 40 | + |
| 41 | + //Place pivot at position [end - 1] |
| 42 | + swap(list[middle], list[end - 1]); |
| 43 | + return list[end - 1]; |
| 44 | + } |
| 45 | + |
24 | 46 | /**
|
25 | 47 | * the quick-sort partition routine
|
26 | 48 | */
|
27 | 49 | template<typename T>
|
28 | 50 | static int __partition(T list[],int begin, int end) {
|
29 |
| - int pivot_idx = RANDOM(begin,end); |
30 |
| - T pivot = list[pivot_idx]; |
31 |
| - swap(list[begin], list[pivot_idx]); |
32 |
| - |
33 |
| - int i = begin + 1; |
34 |
| - int j = end; |
35 |
| - |
36 |
| - while(i <= j) { |
37 |
| - while((i <= end) && (list[i] <= pivot)) |
38 |
| - i++; |
39 |
| - while((j >= begin) && (list[j] > pivot)) |
40 |
| - j--; |
| 51 | + T pivot = __median3<T>(list, begin, end); |
| 52 | + |
| 53 | + int i = begin; |
| 54 | + int j = end - 1; |
| 55 | + |
| 56 | + while(i < j) { |
| 57 | + while(list[++i] < pivot) {} |
| 58 | + while(pivot < list[--j]) {} |
41 | 59 | if(i < j)
|
42 | 60 | swap(list[i],list[j]);
|
43 | 61 | }
|
44 | 62 |
|
45 |
| - swap(list[begin],list[j]); |
46 |
| - return j; // final pivot position |
| 63 | + swap(list[i],list[end - 1]); |
| 64 | + return i; // final pivot position |
47 | 65 | }
|
48 | 66 |
|
49 | 67 | /**
|
50 | 68 | * quick sort an array of range [begin, end]
|
51 | 69 | */
|
52 | 70 | template<typename T>
|
53 | 71 | static void quicksort(T list[],int begin,int end) {
|
54 |
| - if( begin < end) { |
| 72 | + if( begin + 1 < end) { |
55 | 73 | int pivot_idx = __partition<T>(list, begin, end);
|
56 | 74 | quicksort(list, begin, pivot_idx-1);
|
57 | 75 | quicksort(list, pivot_idx+1, end);
|
| 76 | + } else if ( begin + 1 == end) { |
| 77 | + if (list[begin + 1] > list[end]) |
| 78 | + swap(list[begin + 1], list[end]); |
58 | 79 | }
|
59 | 80 | }
|
60 | 81 | }
|
|
0 commit comments