Browse Source

Add `sort.binary_search` (uses interpolation sort for ordered numeric types)

gingerBill 5 years ago
parent
commit
7d11ee605c
2 changed files with 55 additions and 1 deletions
  1. 41 0
      core/sort/sort.odin
  2. 14 1
      examples/demo/demo.odin

+ 41 - 0
core/sort/sort.odin

@@ -286,3 +286,44 @@ compare_strings :: proc(a, b: string) -> int {
 	y := transmute(mem.Raw_String)b;
 	return mem.compare_byte_ptrs(x.data, y.data, min(x.len, y.len));
 }
+
+
+binary_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
+	where intrinsics.type_is_ordered(T) #no_bounds_check {
+
+
+	n := len(array);
+	switch n {
+	case 0:
+		return -1, false;
+	case 1:
+		if array[0] == key {
+			return 0, true;
+		}
+		return -1, false;
+	}
+
+	lo, hi := 0, n-1;
+
+	for array[hi] != array[lo] && key >= array[lo] && key <= array[hi] {
+		when intrinsics.type_is_ordered_numeric(T) {
+			// NOTE(bill): This is technically interpolation search
+			m := lo + int((key - array[lo]) * T(hi - lo) / (array[hi] - array[lo]));
+		} else {
+			m := (lo + hi)/2;
+		}
+		switch {
+		case array[m] < key:
+			lo = m + 1;
+		case key < array[m]:
+			hi = m - 1;
+		case:
+			return m, true;
+		}
+	}
+
+	if key == array[lo] {
+		return lo, true;
+	}
+	return -1, false;
+}

+ 14 - 1
examples/demo/demo.odin

@@ -7,6 +7,7 @@ import "core:thread"
 import "core:time"
 import "core:reflect"
 import "core:runtime"
+import "core:sort"
 import "intrinsics"
 
 
@@ -1978,7 +1979,19 @@ pure_procedures :: proc() {
 }
 
 main :: proc() {
-	when true {
+	x := [?]f32{1, 1, 5, 6, 7, 8, 9, 10, 15, 15};
+	i, ok := sort.binary_search(x[:], 7);
+	fmt.println(x);
+	fmt.println(i, ok);
+
+	y := [?]string{"apple", "hello", "goodbye", "what?"};
+	sort.quick_sort(y[:]);
+	j, y_ok := sort.binary_search(y[:], "goodbye");
+	fmt.println(y);
+	fmt.println(j, y_ok);
+
+
+	when false {
 		the_basics();
 		control_flow();
 		named_proc_return_parameters();