diff --git a/src/lib/sort.rs b/src/lib/sort.rs index 1d149954cff40..9e20e7e178569 100644 --- a/src/lib/sort.rs +++ b/src/lib/sort.rs @@ -4,6 +4,7 @@ import vec::slice; export lteq; export merge_sort; export quick_sort; +export quick_sort3; type lteq[T] = fn(&T a, &T b) -> bool; @@ -52,18 +53,12 @@ fn swap[T](vec[mutable T] arr, uint x, uint y) { fn part[T](lteq[T] compare_func, vec[mutable T] arr, uint left, uint right, uint pivot) -> uint { - fn compare[T](lteq[T] compare_func, vec[mutable T]arr, - uint arr_idx, &T arr_value) -> bool { - - ret compare_func(arr.(arr_idx),arr_value); - } - auto pivot_value = arr.(pivot); swap[T](arr, pivot, right); let uint storage_index = left; let uint i = left; while (i= j) { + break; + } + swap[T](arr, i as uint, j as uint); + if (compare_func_eq(arr.(i), v)) { + p += 1; + swap[T](arr, p as uint, i as uint); + } + if (compare_func_eq(v, arr.(j))) { + q -= 1; + swap[T](arr, j as uint, q as uint); + } + } + swap[T](arr, i as uint, right as uint); + j = i - 1; + i += 1; + + let int k = left; + while (k < p) { + swap[T](arr, k as uint, j as uint); + k += 1; + j -= 1; + if (k == vec::len[T](arr) as int) { + break; + } + } + k = right - 1; + while (k > q) { + swap[T](arr, i as uint, k as uint); + k -= 1; + i += 1; + if (k == 0) { + break; + } + } + + qsort3[T](compare_func_lt, compare_func_eq, arr, left, j); + qsort3[T](compare_func_lt, compare_func_eq, arr, i, right); +} + +fn quick_sort3[T](lteq[T] compare_func_lt, lteq[T] compare_func_eq, + vec[mutable T] arr) { + if (vec::len[T](arr) == 0u) { + ret; + } + qsort3[T](compare_func_lt, compare_func_eq, arr, 0, + (vec::len[T](arr) as int) - 1); +} + // Local Variables: // mode: rust; // fill-column: 78; diff --git a/src/test/run-pass/lib-qsort3.rs b/src/test/run-pass/lib-qsort3.rs new file mode 100644 index 0000000000000..f91a2cb8cadcb --- /dev/null +++ b/src/test/run-pass/lib-qsort3.rs @@ -0,0 +1,66 @@ +use std; + +fn check_sort(vec[mutable int] v1, vec[mutable int] v2) { + auto len = std::vec::len[int](v1); + + fn lt(&int a, &int b) -> bool { + ret a < b; + } + fn equal(&int a, &int b) -> bool { + ret a == b; + } + auto f1 = lt; + auto f2 = equal; + std::sort::quick_sort3[int](f1, f2, v1); + auto i = 0u; + while (i < len) { + log v2.(i); + assert (v2.(i) == v1.(i)); + i += 1u; + } +} + + +fn main() { + { + auto v1 = [mutable 3,7,4,5,2,9,5,8]; + auto v2 = [mutable 2,3,4,5,5,7,8,9]; + check_sort(v1, v2); + } + + { + auto v1 = [mutable 1,1,1]; + auto v2 = [mutable 1,1,1]; + check_sort(v1, v2); + } + + { + let vec[mutable int] v1 = [mutable]; + let vec[mutable int] v2 = [mutable]; + check_sort(v1, v2); + } + + { + auto v1 = [mutable 9]; + auto v2 = [mutable 9]; + check_sort(v1, v2); + } + + { + auto v1 = [mutable 9,3,3,3,9]; + auto v2 = [mutable 3,3,3,9,9]; + check_sort(v1, v2); + } + +} + +// Local Variables: +// mode: rust; +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: + +