@@ -4,6 +4,7 @@ import vec::slice;
4
4
export lteq;
5
5
export merge_sort;
6
6
export quick_sort;
7
+ export quick_sort3;
7
8
8
9
type lteq [ T ] = fn ( & T a, & T b) -> bool;
9
10
@@ -52,18 +53,12 @@ fn swap[T](vec[mutable T] arr, uint x, uint y) {
52
53
fn part[ T ] ( lteq[ T ] compare_func, vec[ mutable T ] arr, uint left,
53
54
uint right, uint pivot) -> uint {
54
55
55
- fn compare[ T ] ( lteq[ T ] compare_func, vec[ mutable T ] arr,
56
- uint arr_idx, & T arr_value) -> bool {
57
-
58
- ret compare_func ( arr. ( arr_idx) , arr_value) ;
59
- }
60
-
61
56
auto pivot_value = arr. ( pivot) ;
62
57
swap[ T ] ( arr, pivot, right) ;
63
58
let uint storage_index = left;
64
59
let uint i = left;
65
60
while ( i<right) {
66
- if ( compare [ T ] ( compare_func, arr, i , pivot_value) ) {
61
+ if ( compare_func ( arr. ( i ) , pivot_value) ) {
67
62
swap[ T ] ( arr, i, storage_index) ;
68
63
storage_index += 1 u;
69
64
}
@@ -95,6 +90,86 @@ fn quick_sort[T](lteq[T] compare_func, vec[mutable T] arr) {
95
90
qsort[ T ] ( compare_func, arr, 0 u, ( len[ T ] ( arr) ) - 1 u) ;
96
91
}
97
92
93
+
94
+ // Based on algorithm presented by Sedgewick and Bentley here:
95
+ // http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf
96
+ // According to these slides this is the algorithm of choice for
97
+ // 'randomly ordered keys, abstract compare' & 'small number of key values'
98
+
99
+ fn qsort3[ T ] ( lteq[ T ] compare_func_lt, lteq[ T ] compare_func_eq,
100
+ vec[ mutable T ] arr, int left, int right) {
101
+
102
+ if ( right <= left) {
103
+ ret;
104
+ }
105
+
106
+ let T v = arr. ( right) ;
107
+ let int i = left - 1 ;
108
+ let int j = right;
109
+ let int p = i;
110
+ let int q = j;
111
+
112
+ while ( true ) {
113
+ i += 1 ;
114
+ while ( compare_func_lt ( arr. ( i) , v) ) {
115
+ i += 1 ;
116
+ }
117
+ j -= 1 ;
118
+ while ( compare_func_lt ( v, arr. ( j) ) ) {
119
+ if ( j == left) {
120
+ break ;
121
+ }
122
+ j -= 1 ;
123
+ }
124
+ if ( i >= j) {
125
+ break ;
126
+ }
127
+ swap[ T ] ( arr, i as uint , j as uint ) ;
128
+ if ( compare_func_eq ( arr. ( i) , v) ) {
129
+ p += 1 ;
130
+ swap[ T ] ( arr, p as uint , i as uint ) ;
131
+ }
132
+ if ( compare_func_eq ( v, arr. ( j) ) ) {
133
+ q -= 1 ;
134
+ swap[ T ] ( arr, j as uint , q as uint ) ;
135
+ }
136
+ }
137
+ swap[ T ] ( arr, i as uint , right as uint ) ;
138
+ j = i - 1 ;
139
+ i += 1 ;
140
+
141
+ let int k = left;
142
+ while ( k < p) {
143
+ swap[ T ] ( arr, k as uint , j as uint ) ;
144
+ k += 1 ;
145
+ j -= 1 ;
146
+ if ( k == vec:: len[ T ] ( arr) as int ) {
147
+ break ;
148
+ }
149
+ }
150
+ k = right - 1 ;
151
+ while ( k > q) {
152
+ swap[ T ] ( arr, i as uint , k as uint ) ;
153
+ k -= 1 ;
154
+ i += 1 ;
155
+ if ( k == 0 ) {
156
+ break ;
157
+ }
158
+ }
159
+
160
+ qsort3[ T ] ( compare_func_lt, compare_func_eq, arr, left, j) ;
161
+ qsort3[ T ] ( compare_func_lt, compare_func_eq, arr, i, right) ;
162
+ }
163
+
164
+ fn quick_sort3[ T ] ( lteq[ T ] compare_func_lt, lteq[ T ] compare_func_eq,
165
+ vec[ mutable T ] arr) {
166
+ if ( vec:: len[ T ] ( arr) == 0 u) {
167
+ ret;
168
+ }
169
+ qsort3[ T ] ( compare_func_lt, compare_func_eq, arr, 0 ,
170
+ ( vec:: len[ T ] ( arr) as int ) - 1 ) ;
171
+ }
172
+
98
173
// Local Variables:
99
174
// mode: rust;
100
175
// fill-column: 78;
0 commit comments