golang sort包Search方法实例

函数声明

func Search(n int, f func(int) bool) int

函数作用

Search函数采用二分法搜索找到[0, n)区间内最小的满足f(i)==true的值i。实现逻辑是,Search函数希望f在输入位于区间[0, n)的前面某部分(可以为空)时返回假,而在输入位于剩余至结尾的部分(可以为空)时返回真;Search函数会返回满足f(i)==true的最小值i。如果没有该值,函数会返回n。注意,未找到时的返回值不是-1,这一点和strings.Index等函数不同。Search函数只会用区间[0, n)内的值调用f。

note:通过看源码和测试该函数不一定能找到最小的满足f(i)==true的值,不知道是不是GO的bug,还是自己哪里理解有误,还在研究

源码分析

func Search(n int, f func(int) bool) int {
	i, j := 0, n
	for i < j {
        //计算二分值,等同于 (i+j) /2 
        //没有使用(i+j)/2的原因是 为了避免数值太大时,溢出
		h := int(uint(i+j) >> 1) 
		// i ≤ h < j
		if !f(h) {
            //f(h)为false时,将i从二分位向后移(查询后面是否有f(n)为true的值)
            //这里也可以看出来i后移之后i前面的值就不会在扫描了
            //如果i后面的值f(n)的结果都是false,i前面的值有f(n)为true也扫描不到的
			i = h + 1 // preserves f(i-1) == false
		} else {
            //f(h)为true时,将最大值j前移到二分位(查询前面是否还有为ture的如果没有,则这个就是最小值)
			j = h // preserves f(j) == true
		}
	}
	// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
	return i
}

测试实例

1.二分位是true,向前查询

	data := []int{10, 25, 11, 24, 17, 26}
	i := sort.Search(len(data), func(i int) bool {
		return data[i] >= 23
	})
	fmt.Println("最终的结果为", i)  // 1  

2.二分位是false,向后查询

	data := []int{10, 22, 11, 22, 17, 26}
	i := sort.Search(len(data), func(i int) bool {
		return data[i] >= 23
	})
	fmt.Println("最终的结果为", i)   //最终的结果为5

3.二分位是false,向后查询(但是二分位前面是存在f(n)为true的)

	data := []int{10, 25, 11, 22, 17, 26}
	i := sort.Search(len(data), func(i int) bool {
		return data[i] >= 23
	})
	fmt.Println("最终的结果为", i)  //最终的结果为5
    //可以看到 i=1的 25是没有找到的

4.没有找到合适的,返回的i值为n

	data := []int{10, 25, 11, 22, 17, 22}
	i := sort.Search(len(data), func(i int) bool {
		return data[i] >= 23
	})
	fmt.Println("最终的结果为", i)   //6

猜你喜欢

转载自blog.csdn.net/u014270740/article/details/89466406
今日推荐