Golang 二分查找
Golang Binary search
我正在练习面试算法,现在用 Go 编写代码。目的是练习基本的面试算法,以及我的围棋技能。我正在尝试对数字数组执行二进制搜索。
package main
import "fmt"
func main() {
searchField := []int{2, 5, 8, 12, 16, 23, 38, 56, 72, 91}
searchNumber := 23
fmt.Println("Running Program")
fmt.Println("Searching list of numbers: ", searchField)
fmt.Println("Searching for number: ", searchNumber)
numFound := false
//searchCount not working. Belongs in second returned field
result, _ := binarySearch2(searchField, len(searchField), searchNumber, numFound)
fmt.Println("Found! Your number is found in position: ", result)
//fmt.Println("Your search required ", searchCount, " cycles with the Binary method.")
}
func binarySearch2(a []int, field int, search int, numFound bool) (result int, searchCount int) {
//searchCount removed for now.
searchCount, i := 0, 0
for !numFound {
searchCount++
mid := i + (field-i)/2
if search == a[mid] {
numFound = true
result = mid
return result, searchCount
} else if search > a[mid] {
field++
//i = mid + 1 causes a stack overflow
return binarySearch2(a, field, search, numFound)
}
field = mid
return binarySearch2(a, field, search, numFound)
}
return result, searchCount
}
我遇到的主要问题是:
1) 当列表中的数字高于我的中间搜索时,我真的是在继续二分搜索,还是已经变成了顺序搜索?我该如何解决?我放置的另一个选项已被注释掉,因为它会导致堆栈溢出。
2) 我想添加步数以查看完成搜索需要多少步。也可以与其他搜索方法一起使用。如果我按原样打印出搜索计数,它总是读取一个。那是因为我需要在方法中 return 它(因此在 header 中调用它)吗?
我知道 Go 有简化这个过程的方法。我正在努力增加我的知识和编码技能。感谢您的意见。
你没有正确地进行二进制搜索。首先,你的 for
循环是无用的,因为条件树中的每个分支都有一个 return 语句,所以它永远不会 运行 超过一次迭代。看起来你开始迭代编码,然后交换到递归设置,但只转换了一半。
二分搜索的思想是你有一个高索引和低索引并搜索它们之间的中间点。你没有这样做,你只是增加 field
变量并再次尝试(这将导致你搜索每个索引两次,直到你找到项目或段错误 运行ning 结束名单)。但是,在 Go 中,您不需要跟踪高索引和低索引,因为您可以根据需要简单地对搜索字段进行细分。
这是一个更优雅的递归版本:
func binarySearch(a []int, search int) (result int, searchCount int) {
mid := len(a) / 2
switch {
case len(a) == 0:
result = -1 // not found
case a[mid] > search:
result, searchCount = binarySearch(a[:mid], search)
case a[mid] < search:
result, searchCount = binarySearch(a[mid+1:], search)
if result >= 0 { // if anything but the -1 "not found" result
result += mid + 1
}
default: // a[mid] == search
result = mid // found
}
searchCount++
return
}
func BinarySearch(array []int, target int) int {
startIndex := 0
endIndex := len(array) - 1
midIndex := len(array) / 2
for startIndex <= endIndex {
value := array[midIndex]
if value == target {
return midIndex
}
if value > target {
endIndex = midIndex - 1
midIndex = (startIndex + endIndex) / 2
continue
}
startIndex = midIndex + 1
midIndex = (startIndex + endIndex) / 2
}
return -1
}
func BinarySearch(a []int, x int) int {
r := -1 // not found
start := 0
end := len(a) - 1
for start <= end {
mid := (start + end) / 2;
if a[mid] == x {
r = mid // found
break
} else if a[mid] < x {
start = mid + 1
} else if a[mid] > x {
end = mid - 1
}
}
return r
}
func search(nums []int, target, lo, hi int) int {
if(lo > hi) {
return -1
}
mid := lo + (hi -lo) /2
if(nums[mid]< target){
return search2(nums, target,mid+1, hi)
}
if (nums[mid]> target){
return search2(nums, target,lo, mid -1)
}
return mid
}
我正在练习面试算法,现在用 Go 编写代码。目的是练习基本的面试算法,以及我的围棋技能。我正在尝试对数字数组执行二进制搜索。
package main
import "fmt"
func main() {
searchField := []int{2, 5, 8, 12, 16, 23, 38, 56, 72, 91}
searchNumber := 23
fmt.Println("Running Program")
fmt.Println("Searching list of numbers: ", searchField)
fmt.Println("Searching for number: ", searchNumber)
numFound := false
//searchCount not working. Belongs in second returned field
result, _ := binarySearch2(searchField, len(searchField), searchNumber, numFound)
fmt.Println("Found! Your number is found in position: ", result)
//fmt.Println("Your search required ", searchCount, " cycles with the Binary method.")
}
func binarySearch2(a []int, field int, search int, numFound bool) (result int, searchCount int) {
//searchCount removed for now.
searchCount, i := 0, 0
for !numFound {
searchCount++
mid := i + (field-i)/2
if search == a[mid] {
numFound = true
result = mid
return result, searchCount
} else if search > a[mid] {
field++
//i = mid + 1 causes a stack overflow
return binarySearch2(a, field, search, numFound)
}
field = mid
return binarySearch2(a, field, search, numFound)
}
return result, searchCount
}
我遇到的主要问题是:
1) 当列表中的数字高于我的中间搜索时,我真的是在继续二分搜索,还是已经变成了顺序搜索?我该如何解决?我放置的另一个选项已被注释掉,因为它会导致堆栈溢出。
2) 我想添加步数以查看完成搜索需要多少步。也可以与其他搜索方法一起使用。如果我按原样打印出搜索计数,它总是读取一个。那是因为我需要在方法中 return 它(因此在 header 中调用它)吗?
我知道 Go 有简化这个过程的方法。我正在努力增加我的知识和编码技能。感谢您的意见。
你没有正确地进行二进制搜索。首先,你的 for
循环是无用的,因为条件树中的每个分支都有一个 return 语句,所以它永远不会 运行 超过一次迭代。看起来你开始迭代编码,然后交换到递归设置,但只转换了一半。
二分搜索的思想是你有一个高索引和低索引并搜索它们之间的中间点。你没有这样做,你只是增加 field
变量并再次尝试(这将导致你搜索每个索引两次,直到你找到项目或段错误 运行ning 结束名单)。但是,在 Go 中,您不需要跟踪高索引和低索引,因为您可以根据需要简单地对搜索字段进行细分。
这是一个更优雅的递归版本:
func binarySearch(a []int, search int) (result int, searchCount int) {
mid := len(a) / 2
switch {
case len(a) == 0:
result = -1 // not found
case a[mid] > search:
result, searchCount = binarySearch(a[:mid], search)
case a[mid] < search:
result, searchCount = binarySearch(a[mid+1:], search)
if result >= 0 { // if anything but the -1 "not found" result
result += mid + 1
}
default: // a[mid] == search
result = mid // found
}
searchCount++
return
}
func BinarySearch(array []int, target int) int {
startIndex := 0
endIndex := len(array) - 1
midIndex := len(array) / 2
for startIndex <= endIndex {
value := array[midIndex]
if value == target {
return midIndex
}
if value > target {
endIndex = midIndex - 1
midIndex = (startIndex + endIndex) / 2
continue
}
startIndex = midIndex + 1
midIndex = (startIndex + endIndex) / 2
}
return -1
}
func BinarySearch(a []int, x int) int {
r := -1 // not found
start := 0
end := len(a) - 1
for start <= end {
mid := (start + end) / 2;
if a[mid] == x {
r = mid // found
break
} else if a[mid] < x {
start = mid + 1
} else if a[mid] > x {
end = mid - 1
}
}
return r
}
func search(nums []int, target, lo, hi int) int {
if(lo > hi) {
return -1
}
mid := lo + (hi -lo) /2
if(nums[mid]< target){
return search2(nums, target,mid+1, hi)
}
if (nums[mid]> target){
return search2(nums, target,lo, mid -1)
}
return mid
}