Skip to content

Commit

Permalink
二分查找的变体 by golang
Browse files Browse the repository at this point in the history
  • Loading branch information
leotyliu(刘天一) committed Oct 29, 2018
1 parent d2954eb commit 587f438
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 0 deletions.
108 changes: 108 additions & 0 deletions go/15_binarysearch/binarysearch.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,111 @@ func bs(a []int, v int, low, high int) int {
return bs(a, v, mid+1, high)
}
}

//查找第一个等于给定值的元素
func BinarySearchFirst(a []int, v int) int {
n := len(a)
if n == 0 {
return -1
}

low := 0
high := n - 1
for low <= high {
mid := (low + high) >> 1
if a[mid] > v {
high = mid - 1
} else if a[mid] < v {
low = mid + 1
} else {
if mid == 0 || a[mid-1] != v {
return mid
} else {
high = mid - 1
}
}
}

return -1
}

//查找最后一个值等于给定值的元素
func BinarySearchLast(a []int, v int) int {
n := len(a)
if n == 0 {
return -1
}

low := 0
high := n - 1
for low <= high {
mid := (low + high) >> 1
if a[mid] > v {
high = mid - 1
} else if a[mid] < v {
low = mid + 1
} else {
if mid == n-1 || a[mid+1] != v {
return mid
} else {
low = mid + 1
}
}
}

return -1
}

//查找第一个大于等于给定值的元素
func BinarySearchFirstGT(a []int, v int) int {
n := len(a)
if n == 0 {
return -1
}

low := 0
high := n - 1
for low <= high {
mid := (high + low) >> 1
if a[mid] > v {
high = mid - 1
} else if a[mid] < v {
low = mid + 1
} else {
if mid != n-1 && a[mid+1] > v {
return mid + 1
} else {
low = mid + 1
}
}
}

return -1
}

//查找最后一个小于等于给定值的元素
func BinarySearchLastLT(a []int, v int) int {
n := len(a)
if n == 0 {
return -1
}

low := 0
high := n - 1
for low <= high {
mid := (low + high) >> 1
if a[mid] > v {
high = mid - 1
} else if a[mid] < v {
low = mid + 1
} else {
if mid == 0 || a[mid-1] < v {
return mid - 1
} else {
high = mid - 1
}
}
}

return -1
}
76 changes: 76 additions & 0 deletions go/15_binarysearch/binarysearch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,79 @@ func TestBinarySearchRecursive(t *testing.T) {
t.Fatal(BinarySearch(a, 4))
}
}

func TestBinarySearchFirst(t *testing.T) {
var a []int

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchFirst(a, 2) != 1 {
t.Fatal(BinarySearchFirst(a, 2))
}

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchFirst(a, 3) != 4 {
t.Fatal(BinarySearchFirst(a, 3))
}
}

func TestBinarySearchLast(t *testing.T) {
var a []int

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchLast(a, 2) != 3 {
t.Fatal(BinarySearchLast(a, 2))
}

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchLast(a, 3) != 4 {
t.Fatal(BinarySearchLast(a, 3))
}
}

func TestBinarySearchFirstGT(t *testing.T) {
var a []int

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchFirstGT(a, 2) != 4 {
t.Fatal(BinarySearchFirstGT(a, 2))
}

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchFirstGT(a, 1) != 1 {
t.Fatal(BinarySearchFirstGT(a, 1))
}

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchFirstGT(a, 3) != 5 {
t.Fatal(BinarySearchFirstGT(a, 3))
}

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchFirstGT(a, 4) != -1 {
t.Fatal(BinarySearchFirstGT(a, 4))
}
}

func TestBinarySearchLastLT(t *testing.T) {
var a []int

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchLastLT(a, 2) != 0 {
t.Fatal(BinarySearchLastLT(a, 2))
}

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchLastLT(a, 1) != -1 {
t.Fatal(BinarySearchLastLT(a, 1))
}

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchLastLT(a, 3) != 3 {
t.Fatal(BinarySearchLastLT(a, 3))
}

a = []int{1, 2, 2, 2, 3, 4}
if BinarySearchLastLT(a, 4) != 4 {
t.Fatal(BinarySearchLastLT(a, 4))
}
}

0 comments on commit 587f438

Please sign in to comment.