authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-31 00:40:43+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-31 00:40:43+01:00
logfd8d8afb243d5a6ceadaf38ad08b72be915fce2e
tree2f5ff7f3a4f4864a7836a16d6c452be58a2443df
parentcbd42e44d6321e59c7e89019e28bcf5299210795

stdlib: Add binary search function


1 files changed, 61 insertions(+), 0 deletions(-)

lib/std/sort.zig+61
......@@ -5,6 +5,67 @@ const mem = std.mem;
55const math = std.math;
66const builtin = @import("builtin");
77
8pub fn binarySearch(comptime T: type, items: []T, comptime compareFn: fn (val: T) math.Order) ?usize {
9 if (items.len < 1)
10 return null;
11
12 var left: usize = 0;
13 var right: usize = items.len - 1;
14
15 while (left <= right) {
16 // Avoid overflowing in the midpoint calculation
17 const mid = left + (right - left) / 2;
18 // Compare the midpoint element with the key
19 switch (compareFn(items[mid])) {
20 .eq => return mid,
21 .lt => left = mid + 1,
22 .gt => right = mid - 1,
23 }
24 }
25
26 return null;
27}
28
29test "std.sort.binarySearch" {
30 const S = struct {
31 fn makeComparisonPred(comptime T: type, value: T) type {
32 return struct {
33 fn pred(v: T) math.Order {
34 return math.order(v, value);
35 }
36 };
37 }
38 };
39 testing.expectEqual(
40 @as(?usize, null),
41 binarySearch(u32, &[_]u32{}, S.makeComparisonPred(u32, 1).pred),
42 );
43 testing.expectEqual(
44 @as(?usize, 0),
45 binarySearch(u32, &[_]u32{1}, S.makeComparisonPred(u32, 1).pred),
46 );
47 testing.expectEqual(
48 @as(?usize, null),
49 binarySearch(u32, &[_]u32{0}, S.makeComparisonPred(u32, 1).pred),
50 );
51 testing.expectEqual(
52 @as(?usize, 4),
53 binarySearch(u32, &[_]u32{ 1, 2, 3, 4, 5 }, S.makeComparisonPred(u32, 5).pred),
54 );
55 testing.expectEqual(
56 @as(?usize, 0),
57 binarySearch(u32, &[_]u32{ 2, 4, 8, 16, 32, 64 }, S.makeComparisonPred(u32, 2).pred),
58 );
59 testing.expectEqual(
60 @as(?usize, 1),
61 binarySearch(i32, &[_]i32{ -7, -4, 0, 9, 10 }, S.makeComparisonPred(i32, -4).pred),
62 );
63 testing.expectEqual(
64 @as(?usize, 3),
65 binarySearch(i32, &[_]i32{ -100, -25, 2, 98, 99, 100 }, S.makeComparisonPred(i32, 98).pred),
66 );
67}
68
869/// Stable in-place sort. O(n) best case, O(pow(n, 2)) worst case. O(1) memory (no allocator required).
970pub fn insertionSort(comptime T: type, items: []T, lessThan: fn (lhs: T, rhs: T) bool) void {
1071 var i: usize = 1;