|
19 | 19 | #define __QUICKSORT_H__ |
20 | 20 |
|
21 | 21 | #include <generic.h> |
22 | | -#include <cassert> |
23 | 22 |
|
24 | 23 | 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 | | - |
46 | 24 | /** |
47 | 25 | * the quick-sort partition routine |
48 | 26 | */ |
49 | 27 | template<typename T> |
50 | 28 | static int __partition(T list[],int begin, int end) { |
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]) {} |
| 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--; |
59 | 41 | if(i < j) |
60 | 42 | swap(list[i],list[j]); |
61 | 43 | } |
62 | 44 |
|
63 | | -swap(list[i],list[end - 1]); |
64 | | -return i; // final pivot position |
| 45 | +swap(list[begin],list[j]); |
| 46 | +return j; // final pivot position |
65 | 47 | } |
66 | 48 |
|
67 | 49 | /** |
68 | 50 | * quick sort an array of range [begin, end] |
69 | 51 | */ |
70 | 52 | template<typename T> |
71 | 53 | static void quicksort(T list[],int begin,int end) { |
72 | | -if( begin + 1 < end) { |
| 54 | +if( begin < end) { |
73 | 55 | int pivot_idx = __partition<T>(list, begin, end); |
74 | 56 | quicksort(list, begin, pivot_idx-1); |
75 | 57 | quicksort(list, pivot_idx+1, end); |
76 | | -} else if ( begin + 1 == end) { |
77 | | -if (list[begin] > list[end]) |
78 | | -swap(list[begin], list[end]); |
79 | 58 | } |
80 | 59 | } |
81 | 60 | } |
|
0 commit comments