authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-09 12:12:25-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2016-11-09 12:12:25-05:00
log1e0b493276bd645e0162fb5edac03bbc8911d0b1
tree77c68dfe86bff850a4909365b24721d2b7c2a303
parente4271f4fb26ce7245f73bcf9ffd33d1bd47a02e6
parent4b55966a160b1fc79a666770e3d163f52331164a

Merge pull request #209 from stereosteve/sort

quicksort

3 files changed, 113 insertions(+), 0 deletions(-)

CMakeLists.txt+1
......@@ -222,6 +222,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/net.zig" DESTINATION "${ZIG_STD_DEST}")
222222install(FILES "${CMAKE_SOURCE_DIR}/std/os.zig" DESTINATION "${ZIG_STD_DEST}")
223223install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
224224install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}")
225install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
225226install(FILES "${CMAKE_SOURCE_DIR}/std/str.zig" DESTINATION "${ZIG_STD_DEST}")
226227install(FILES "${CMAKE_SOURCE_DIR}/std/test_runner.zig" DESTINATION "${ZIG_STD_DEST}")
227228install(FILES "${CMAKE_SOURCE_DIR}/std/test_runner_libc.zig" DESTINATION "${ZIG_STD_DEST}")
std/index.zig+1
......@@ -4,6 +4,7 @@ pub const os = @import("os.zig");
44pub const math = @import("math.zig");
55pub const str = @import("str.zig");
66pub const cstr = @import("cstr.zig");
7pub const sort = @import("sort.zig");
78pub const net = @import("net.zig");
89pub const list = @import("list.zig");
910pub const hash_map = @import("hash_map.zig");
std/sort.zig created+111
......@@ -0,0 +1,111 @@
1const assert = @import("debug.zig").assert;
2const str = @import("str.zig");
3const math = @import("math.zig");
4
5pub const Cmp = math.Cmp;
6
7pub fn sort(inline T: type, array: []T, inline cmp: fn(a: T, b: T)->Cmp) {
8 if (array.len > 0) {
9 quicksort(T, array, 0, array.len - 1, cmp);
10 }
11}
12
13fn quicksort(inline T: type, array: []T, left: usize, right: usize, inline cmp: fn(a: T, b: T)->Cmp) {
14 var i = left;
15 var j = right;
16 var p = (i + j) / 2;
17
18 while (i <= j) {
19 while (cmp(array[i], array[p]) == Cmp.Less) {
20 i += 1;
21 }
22 while (cmp(array[j], array[p]) == Cmp.Greater) {
23 j -= 1;
24 }
25 if (i <= j) {
26 const tmp = array[i];
27 array[i] = array[j];
28 array[j] = tmp;
29 i += 1;
30 if (j > 0) j -= 1;
31 }
32 }
33
34 if (left < j) quicksort(T, array, left, j, cmp);
35 if (i < right) quicksort(T, array, i, right, cmp);
36}
37
38pub fn i32asc(a: i32, b: i32) -> Cmp {
39 return if (a > b) Cmp.Greater else if (a < b) Cmp.Less else Cmp.Equal;
40}
41
42pub fn i32desc(a: i32, b: i32) -> Cmp {
43 return reverse(i32asc(a, b));
44}
45
46pub fn u8asc(a: u8, b: u8) -> Cmp {
47 return if (a > b) Cmp.Greater else if (a < b) Cmp.Less else Cmp.Equal;
48}
49
50pub fn u8desc(a: u8, b: u8) -> Cmp {
51 return reverse(u8asc(a, b));
52}
53
54fn reverse(was: Cmp) -> Cmp {
55 return if (was == Cmp.Greater) Cmp.Less else if (was == Cmp.Less) Cmp.Greater else Cmp.Equal;
56}
57
58// ---------------------------------------
59// tests
60
61fn testSort() {
62 @setFnTest(this, true);
63
64 const u8cases = [][][]u8 {
65 [][]u8{"", ""},
66 [][]u8{"a", "a"},
67 [][]u8{"az", "az"},
68 [][]u8{"za", "az"},
69 [][]u8{"asdf", "adfs"},
70 [][]u8{"one", "eno"},
71 };
72
73 for (u8cases) |case| {
74 sort(u8, case[0], u8asc);
75 assert(str.eql(case[0], case[1]));
76 }
77
78 const i32cases = [][][]i32 {
79 [][]i32{[]i32{}, []i32{}},
80 [][]i32{[]i32{1}, []i32{1}},
81 [][]i32{[]i32{0, 1}, []i32{0, 1}},
82 [][]i32{[]i32{1, 0}, []i32{0, 1}},
83 [][]i32{[]i32{1, -1, 0}, []i32{-1, 0, 1}},
84 [][]i32{[]i32{2, 1, 3}, []i32{1, 2, 3}},
85 };
86
87 for (i32cases) |case| {
88 sort(i32, case[0], i32asc);
89 assert(str.sliceEql(i32, case[0], case[1]));
90 }
91}
92
93fn testSortDesc() {
94 @setFnTest(this, true);
95
96 const revCases = [][][]i32 {
97 [][]i32{[]i32{}, []i32{}},
98 [][]i32{[]i32{1}, []i32{1}},
99 [][]i32{[]i32{0, 1}, []i32{1, 0}},
100 [][]i32{[]i32{1, 0}, []i32{1, 0}},
101 [][]i32{[]i32{1, -1, 0}, []i32{1, 0, -1}},
102 [][]i32{[]i32{2, 1, 3}, []i32{3, 2, 1}},
103 };
104
105 for (revCases) |case| {
106 sort(i32, case[0], i32desc);
107 assert(str.sliceEql(i32, case[0], case[1]));
108 }
109
110}
111