authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-03 16:53:00-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-02-03 16:53:00-05:00
log0fdcd5c4cb335fcb2d637b891e60094b7a34e2b5
tree14a21f75dad026c7800bb9850e1618241f15b0b0
parent1658becb6221f9ffdbfd653c5e295501ac338794
parentdb3aea3a0bfce6af04d941003c6a63e86cfdee1a
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4337 from LemonBoy/stdlib-bsearch

stdlib: Add binary search function

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

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