From 966002db2269cb3ecf51308b53a9c1cd3f0f70ba Mon Sep 17 00:00:00 2001 From: Gregory Eremin Date: Sun, 11 Oct 2015 21:55:50 +0300 Subject: [PATCH] Implemented binary search algorithm --- binary_search.go | 43 +++++++++++++++++++++++++++++++++++++ binary_search_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 binary_search.go create mode 100644 binary_search_test.go diff --git a/binary_search.go b/binary_search.go new file mode 100644 index 0000000..d0704b3 --- /dev/null +++ b/binary_search.go @@ -0,0 +1,43 @@ +package algorithms + +// BinarySearch is an implementation of binary search algorithm. +// Wikipedia: https://en.wikipedia.org/wiki/Binary_search_algorithm +// +// The binary search algorithm begins by comparing the target value to the value +// of the middle element of the sorted array. If the target value is equal to +// the middle element's value, then the position is returned and the search is +// finished. If the target value is less than the middle element's value, then +// the search continues on the lower half of the array; or if the target value +// is greater than the middle element's value, then the search continues on the +// upper half of the array. This process continues, eliminating half of the +// elements, and comparing the target value to the value of the middle element +// of the remaining elements - until the target value is either found (and its +// associated element position is returned), or until the entire array has been +// searched (and "not found" is returned). +func BinarySearch(haystack []int, needle int) (pos int, ok bool) { + if len(haystack) == 0 { + return 0, false + } + if haystack[0] > needle { + return 0, false + } + if haystack[len(haystack)-1] < needle { + return 0, false + } + + first := 0 + last := len(haystack) + for first < last { + mid := first + (last-first)/2 + + if haystack[mid] == needle { + return mid, true + } else if haystack[mid] > needle { + last = mid + } else { + first = mid + 1 + } + } + + return 0, false +} diff --git a/binary_search_test.go b/binary_search_test.go new file mode 100644 index 0000000..436f361 --- /dev/null +++ b/binary_search_test.go @@ -0,0 +1,49 @@ +package algorithms + +import ( + "testing" +) + +func TestBinarySearchEmptyArray(t *testing.T) { + if _, ok := BinarySearch([]int{}, 1); ok { + t.Error("Position should not be found") + } +} + +func TestBinarySearchLowerThanFirstValue(t *testing.T) { + if _, ok := BinarySearch([]int{1, 2, 3, 4, 5}, 0); ok { + t.Error("Position should not be found") + } +} + +func TestBinarySearchHigherThanLastValue(t *testing.T) { + if _, ok := BinarySearch([]int{1, 2, 3, 4, 5}, 6); ok { + t.Error("Position should not be found") + } +} + +func TestBinarySearchNotFound(t *testing.T) { + if _, ok := BinarySearch([]int{1, 2, 4, 5}, 3); ok { + t.Error("Position should not be found") + } +} + +func TestBinarySearchOddSize(t *testing.T) { + pos, ok := BinarySearch([]int{1, 2, 3, 4, 5}, 1) + if !ok { + t.Fatalf("Position should be found") + } + if pos != 0 { + t.Errorf("Expected position %d, got %d", 0, pos) + } +} + +func TestBinarySearchEvenSize(t *testing.T) { + pos, ok := BinarySearch([]int{1, 2, 3, 4, 5, 6}, 6) + if !ok { + t.Fatalf("Position should be found") + } + if pos != 5 { + t.Errorf("Expected position %d, got %d", 5, pos) + } +}