authorgravatar for benjamin.feng@glassdoor.comBenjamin Feng <benjamin.feng@glassdoor.com> 2019-11-18 20:35:03-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-26 13:09:58-05:00
logaca13675332474bad428166b744ec94f806bd2cc
tree644a12f354e6323c9b9dd24fa07dc86b747af01c
parent76f21852f6553fc22612bb82df19184fdb28719e

Optimize binary search algorithm


1 files changed, 20 insertions(+), 24 deletions(-)

lib/std/sort.zig+20-24
...@@ -868,39 +868,35 @@ fn findLastBackward(comptime T: type, items: []T, value: T, range: Range, lessTh...@@ -868,39 +868,35 @@ fn findLastBackward(comptime T: type, items: []T, value: T, range: Range, lessTh
868}868}
869869
870fn binaryFirst(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool) usize {870fn binaryFirst(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool) usize {
871 var start = range.start;871 var curr = range.start;
872 var end = range.end - 1;872 var size = range.length();
873 if (range.start >= range.end) return range.end;873 if (range.start >= range.end) return range.end;
874 while (start < end) {874 while (size > 0) {
875 const mid = start + (end - start) / 2;875 const offset = size % 2;
876 if (lessThan(items[mid], value)) {876
877 start = mid + 1;877 size /= 2;
878 } else {878 const mid = items[curr + size];
879 end = mid;879 if (lessThan(mid, value)) {
880 curr += size + offset;
880 }881 }
881 }882 }
882 if (start == range.end - 1 and lessThan(items[start], value)) {883 return curr;
883 start += 1;
884 }
885 return start;
886}884}
887885
888fn binaryLast(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool) usize {886fn binaryLast(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool) usize {
889 var start = range.start;887 var curr = range.start;
890 var end = range.end - 1;888 var size = range.length();
891 if (range.start >= range.end) return range.end;889 if (range.start >= range.end) return range.end;
892 while (start < end) {890 while (size > 0) {
893 const mid = start + (end - start) / 2;891 const offset = size % 2;
894 if (!lessThan(value, items[mid])) {892
895 start = mid + 1;893 size /= 2;
896 } else {894 const mid = items[curr + size];
897 end = mid;895 if (!lessThan(value, mid)) {
896 curr += size + offset;
898 }897 }
899 }898 }
900 if (start == range.end - 1 and !lessThan(value, items[start])) {899 return curr;
901 start += 1;
902 }
903 return start;
904}900}
905901
906fn mergeInto(comptime T: type, from: []T, A: Range, B: Range, lessThan: fn (T, T) bool, into: []T) void {902fn mergeInto(comptime T: type, from: []T, A: Range, B: Range, lessThan: fn (T, T) bool, into: []T) void {