Think Deep,Work Lean

go语言二分查找法

Posted on By zack

算法

二分查找法(sort.Search)、冒泡法、快排(sort.Sort)

自己实现

二分法,本质就是猜数字游戏。你心中默默想一个数,我来猜,你说大了或是小了,直到最后猜中为止

分析:作为普通人,我们编码,思路一般如下:

  1. 定义一个数字变量 uint target
  2. 定义一个递增数组 var numbers []uint{} -> for i:=0;i<2^8;i++ {...}
  3. 取两指针,分别指向数组的首、尾,然后比较中间值,根据比较结果移动指针,直到结果相等。

所以写出来的代码如下:

func sort(target int, nums []int) int {
    var i,j,mid int = 0,len(nums)-1,0  //起始分别将指针指为数组首尾
    
    for i<j {
        mid := (i+j)/2
        if nums[mid] == target {
            return mid
        }
        if  nums[mid] > target {
            j = mid-1
        }else{
            i = mid +1
        }
    } 
    return -1
}

go语言中的实现

// 第一个参数是递增列表的长度,第二个参数是判断i是否比目的参数大 
// 如果是递减列表,就要判断i是否比目的参数小
// 返回的是递增序列中符合要求的最小的索引
func Search(n int, f func(int) bool) int {
	// Define f(-1) == false and f(n) == true.
	// Invariant: f(i-1) == false, f(j) == true.
	i, j := 0, n
	for i < j {
		h := int(uint(i+j) >> 1) // avoid overflow when computing h
		// i ≤ h < j
		if !f(h) {
			i = h + 1 // preserves f(i-1) == false
		} else {
			j = h // preserves f(j) == true
		}
	}
	// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
	return i
}

分析

  • go源码包中的实现非常简洁,右移一位相当于除以2
  • 传入的是数组的长度n,以及一个函数,函数入参是target,返回的是比较的结果

值得学习的地方是,把参数做为为变量