Skip to content

Commit 32e54df

Browse files
wilsonkbrson
authored andcommitted
---
yaml --- r: 2765 b: refs/heads/master c: 31de8e1 h: refs/heads/master i: 2763: fe2aaa4 v: v3
1 parent cc0461d commit 32e54df

File tree

3 files changed

+149
-8
lines changed

3 files changed

+149
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: ac836dd79c2d7c631ca601dc468de13cb5c785da
2+
refs/heads/master: 31de8e15c0f9575c236fc87fbbf02bd08e3b8842

trunk/src/lib/sort.rs

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import vec::slice;
44
export lteq;
55
export merge_sort;
66
export quick_sort;
7+
export quick_sort3;
78

89
type lteq[T] = fn(&T a, &T b) -> bool;
910

@@ -52,18 +53,12 @@ fn swap[T](vec[mutable T] arr, uint x, uint y) {
5253
fn part[T](lteq[T] compare_func, vec[mutable T] arr, uint left,
5354
uint right, uint pivot) -> uint {
5455

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-
6156
auto pivot_value = arr.(pivot);
6257
swap[T](arr, pivot, right);
6358
let uint storage_index = left;
6459
let uint i = left;
6560
while (i<right) {
66-
if (compare[T](compare_func, arr, i, pivot_value)) {
61+
if (compare_func(arr.(i), pivot_value)) {
6762
swap[T](arr, i, storage_index);
6863
storage_index += 1u;
6964
}
@@ -95,6 +90,86 @@ fn quick_sort[T](lteq[T] compare_func, vec[mutable T] arr) {
9590
qsort[T](compare_func, arr, 0u, (len[T](arr)) - 1u);
9691
}
9792

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) == 0u) {
167+
ret;
168+
}
169+
qsort3[T](compare_func_lt, compare_func_eq, arr, 0,
170+
(vec::len[T](arr) as int) - 1);
171+
}
172+
98173
// Local Variables:
99174
// mode: rust;
100175
// fill-column: 78;

trunk/src/test/run-pass/lib-qsort3.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use std;
2+
3+
fn check_sort(vec[mutable int] v1, vec[mutable int] v2) {
4+
auto len = std::vec::len[int](v1);
5+
6+
fn lt(&int a, &int b) -> bool {
7+
ret a < b;
8+
}
9+
fn equal(&int a, &int b) -> bool {
10+
ret a == b;
11+
}
12+
auto f1 = lt;
13+
auto f2 = equal;
14+
std::sort::quick_sort3[int](f1, f2, v1);
15+
auto i = 0u;
16+
while (i < len) {
17+
log v2.(i);
18+
assert (v2.(i) == v1.(i));
19+
i += 1u;
20+
}
21+
}
22+
23+
24+
fn main() {
25+
{
26+
auto v1 = [mutable 3,7,4,5,2,9,5,8];
27+
auto v2 = [mutable 2,3,4,5,5,7,8,9];
28+
check_sort(v1, v2);
29+
}
30+
31+
{
32+
auto v1 = [mutable 1,1,1];
33+
auto v2 = [mutable 1,1,1];
34+
check_sort(v1, v2);
35+
}
36+
37+
{
38+
let vec[mutable int] v1 = [mutable];
39+
let vec[mutable int] v2 = [mutable];
40+
check_sort(v1, v2);
41+
}
42+
43+
{
44+
auto v1 = [mutable 9];
45+
auto v2 = [mutable 9];
46+
check_sort(v1, v2);
47+
}
48+
49+
{
50+
auto v1 = [mutable 9,3,3,3,9];
51+
auto v2 = [mutable 3,3,3,9,9];
52+
check_sort(v1, v2);
53+
}
54+
55+
}
56+
57+
// Local Variables:
58+
// mode: rust;
59+
// fill-column: 78;
60+
// indent-tabs-mode: nil
61+
// c-basic-offset: 4
62+
// buffer-file-coding-system: utf-8-unix
63+
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
64+
// End:
65+
66+

0 commit comments

Comments
 (0)