diff --git a/binary_insertion_sort.go b/binary_insertion_sort.go new file mode 100644 index 0000000..abe13e6 --- /dev/null +++ b/binary_insertion_sort.go @@ -0,0 +1,28 @@ +package algorithms + +// BinaryInsertionSort is an implementation of binary insertion sort algorithm. +// Wikipedia: https://en.wikipedia.org/wiki/Insertion_sort#Variants +func BinaryInsertionSort(a []int) []int { + for i := 1; i < len(a); i++ { + v := a[i] + low := 0 + high := i + + for low < high { + mid := low + (high-low)/2 + if v < a[mid] { + high = mid + } else { + low = mid + 1 + } + } + + for j := i; j > low; j-- { + a[j] = a[j-1] + } + + a[low] = v + } + + return a +} diff --git a/binary_insertion_sort_test.go b/binary_insertion_sort_test.go new file mode 100644 index 0000000..eb12ae3 --- /dev/null +++ b/binary_insertion_sort_test.go @@ -0,0 +1,18 @@ +package algorithms + +import ( + "testing" +) + +func TestBinaryInsertionSort(t *testing.T) { + testSort(t, BinaryInsertionSort, + []int{5, 3, 1, 4, 2}, + []int{1, 2, 3, 4, 5}, + ) +} + +func BenchmarkBinaryInsertionSort(b *testing.B) { + for i := 0; i < b.N; i++ { + BinaryInsertionSort(unsortedArray()) + } +} diff --git a/insertion_sort_test.go b/insertion_sort_test.go index 43eb88d..03c8346 100644 --- a/insertion_sort_test.go +++ b/insertion_sort_test.go @@ -5,21 +5,21 @@ import ( ) func TestInsertionSort(t *testing.T) { - testInsertionSort(t, InsertionSort, + testSort(t, InsertionSort, []int{5, 3, 1, 4, 2}, []int{1, 2, 3, 4, 5}, ) } func TestInsertionSortOptimized(t *testing.T) { - testInsertionSort(t, InsertionSortOptimized, + testSort(t, InsertionSortOptimized, []int{5, 3, 1, 4, 2}, []int{1, 2, 3, 4, 5}, ) } func TestInsertionSortOptimizedTwoItems(t *testing.T) { - testInsertionSort(t, InsertionSortOptimized, + testSort(t, InsertionSortOptimized, []int{2, 1}, []int{1, 2}, ) @@ -36,30 +36,3 @@ func BenchmarkInsertionSortOptimized(b *testing.B) { InsertionSortOptimized(unsortedArray()) } } - -func testInsertionSort(t *testing.T, sortFun func([]int) []int, a, exp []int) { - s := sortFun(a) - if len(s) != len(exp) { - t.Fatal("Array sizes don't match") - } - for i := 0; i < len(exp); i++ { - if s[i] != exp[i] { - t.Fatalf("Expected sorted array to equal %v, got %v", exp, s) - } - } -} - -func unsortedArray() []int { - return []int{ - 57, 64, 83, 25, 26, 10, 55, 22, 76, 61, - 28, 77, 56, 32, 63, 17, 91, 20, 58, 16, - 1, 51, 88, 82, 24, 70, 81, 35, 49, 39, - 89, 30, 46, 6, 41, 19, 43, 67, 53, 97, - 65, 37, 13, 23, 29, 69, 0, 73, 9, 59, - 96, 34, 66, 79, 27, 14, 40, 80, 98, 2, - 5, 45, 50, 4, 85, 18, 86, 7, 87, 31, - 95, 47, 68, 36, 15, 48, 8, 92, 11, 74, - 78, 52, 44, 42, 54, 84, 12, 21, 38, 99, - 72, 33, 71, 93, 60, 62, 90, 94, 3, 75, - } -} diff --git a/sort_test.go b/sort_test.go new file mode 100644 index 0000000..a23825a --- /dev/null +++ b/sort_test.go @@ -0,0 +1,32 @@ +package algorithms + +import ( + "testing" +) + +func testSort(t *testing.T, sortFun func([]int) []int, a, exp []int) { + s := sortFun(a) + if len(s) != len(exp) { + t.Fatal("Array sizes don't match") + } + for i := 0; i < len(exp); i++ { + if s[i] != exp[i] { + t.Fatalf("Expected sorted array to equal %v, got %v", exp, s) + } + } +} + +func unsortedArray() []int { + return []int{ + 57, 64, 83, 25, 26, 10, 55, 22, 76, 61, + 28, 77, 56, 32, 63, 17, 91, 20, 58, 16, + 1, 51, 88, 82, 24, 70, 81, 35, 49, 39, + 89, 30, 46, 6, 41, 19, 43, 67, 53, 97, + 65, 37, 13, 23, 29, 69, 0, 73, 9, 59, + 96, 34, 66, 79, 27, 14, 40, 80, 98, 2, + 5, 45, 50, 4, 85, 18, 86, 7, 87, 31, + 95, 47, 68, 36, 15, 48, 8, 92, 11, 74, + 78, 52, 44, 42, 54, 84, 12, 21, 38, 99, + 72, 33, 71, 93, 60, 62, 90, 94, 3, 75, + } +}