golang二分查找算法实现过程

 更新时间:2026年06月25日 10:38:56   作者:莫忘初心丶  
这段描述概括了Golang中实现二分查找算法的过程,包括基本步骤、时间复杂度及应用场景,文章详细介绍了二分查找的基本原理和代码实现,并提及了其在有序数组查找中的的高效性,并并讨论了进阶应用场景,如适合开发人员和技术爱好者学习和参考

前言

项目中使用到有序数组查找特定元素,简单记录下Golang中二分查找算法。

二分查找算法简介

二分查找算法是一种在有序数组中查找特定元素的高效算法。

它的基本思想是通过不断将查找范围缩小一半,来快速定位目标元素是否存在。该算法要求数组是有序的,这是因为有序数组的特性允许我们在每一步中排除掉一半的元素。

以下是二分查找的基本步骤:

  1. 初始化: 确定数组的初始搜索范围,通常是整个数组。设定lowhigh分别为搜索范围的最低和最高索引。

  2. 中间元素: 计算中间元素的索引,即mid = (low + high) / 2

  3. 比较: 将目标值与中间元素进行比较。

    • 如果目标值等于中间元素,搜索成功,返回中间元素的索引。
    • 如果目标值小于中间元素,说明目标值可能在左半部分,更新high = mid - 1
    • 如果目标值大于中间元素,说明目标值可能在右半部分,更新low = mid + 1
  4. 循环: 重复上述步骤,直到搜索范围缩小到无法再分割,即low > high。此时,如果目标值存在,返回其索引;否则,返回-1表示目标值不存在。

二分查找的时间复杂度是O(log n),其中n是数组的大小。由于每一步都能将搜索范围减半,因此它在大型有序数组中的性能非常高效。这使得二分查找成为一种常用的查找算法。

请注意,二分查找要求数组是有序的,因此在使用之前需要确保数组有序。

二分查找算法简单实现

package main

import "fmt"

// 二分查找函数
func binarySearch(arr []int, target int) int {
	low, high := 0, len(arr)-1

	for low <= high {
		mid := (low + high) / 2

		if arr[mid] == target {
			return mid // 找到目标值,返回索引
		} else if arr[mid] < target {
			low = mid + 1 // 目标值在右半部分,缩小搜索范围
		} else {
			high = mid - 1 // 目标值在左半部分,缩小搜索范围
		}
	}

	return -1 // 目标值不存在
}

func main() {
	// 示例数组,必须是已排序的数组
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	// 要查找的目标值
	target := 7

	// 调用二分查找算法
	index := binarySearch(arr, target)

	if index != -1 {
		fmt.Printf("目标值 %d 在数组中的索引是 %d\n", target, index)
	} else {
		fmt.Printf("目标值 %d 不存在于数组中\n", target)
	}
}

在这个例子中,binarySearch函数接受一个已排序的数组和目标值作为参数,然后使用二分查找算法找到目标值的索引。

如果找到目标值,返回其索引;如果找不到,返回-1。

main函数中,我们提供了一个已排序的数组和要查找的目标值,然后调用binarySearch函数进行查找。

二分查找算法进阶使用

二分查找算法在进阶使用时,可以通过一些变体或特殊情况的处理来满足更复杂的需求。

以下是一些二分查找算法的进阶使用场景和技巧:

1. 查找第一个或最后一个等于目标值的元素

在有序数组中,如果存在重复元素,可以通过稍作修改,使二分查找找到第一个等于目标值或最后一个等于目标值的元素。

例如,找到数组中第一个等于目标值的索引:

func firstOccurrence(arr []int, target int) int {
    low, high := 0, len(arr)-1
    result := -1

    for low <= high {
        mid := (low + high) / 2

        if arr[mid] == target {
            result = mid     // 记录当前找到的索引
            high = mid - 1   // 继续在左半部分查找
        } else if arr[mid] < target {
            low = mid + 1    // 目标值在右半部分,缩小搜索范围
        } else {
            high = mid - 1   // 目标值在左半部分,缩小搜索范围
        }
    }

    return result
}

2. 查找第一个大于或等于目标值的元素

如果需要找到数组中第一个大于或等于目标值的元素,可以进行相应的调整:

func firstGreaterOrEqual(arr []int, target int) int {
    low, high := 0, len(arr)-1
    result := -1

    for low <= high {
        mid := (low + high) / 2

        if arr[mid] >= target {
            result = mid     // 记录当前找到的索引
            high = mid - 1   // 继续在左半部分查找
        } else {
            low = mid + 1    // 目标值在右半部分,缩小搜索范围
        }
    }

    return result
}

3. 查找最后一个小于或等于目标值的元素

类似地,如果需要找到数组中最后一个小于或等于目标值的元素:

func lastLessOrEqual(arr []int, target int) int {
    low, high := 0, len(arr)-1
    result := -1

    for low <= high {
        mid := (low + high) / 2

        if arr[mid] <= target {
            result = mid     // 记录当前找到的索引
            low = mid + 1    // 继续在右半部分查找
        } else {
            high = mid - 1   // 目标值在左半部分,缩小搜索范围
        }
    }

    return result
}

4. 查找循环有序数组中的元素

如果数组是循环有序的,可以先找到旋转点,然后分别在两个有序部分中进行二分查找。

这些进阶使用场景展示了如何通过适当的调整,使得二分查找算法适用于更多的情况。在实际应用中,根据具体问题的要求,可以进一步定制二分查找算法的逻辑。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 一文掌握go的sync.RWMutex锁

    一文掌握go的sync.RWMutex锁

    这篇文章主要介绍了一文掌握go的sync.RWMutex锁,本文是为了在面试中能快速口述RW锁,并非为了完整解答RW锁的机制,需要的朋友可以参考下
    2023-03-03
  • GO项目实战之Gorm格式化时间字段实现

    GO项目实战之Gorm格式化时间字段实现

    GORM自带的time.Time类型JSON默认输出RFC3339Nano格式的,下面这篇文章主要给大家介绍了关于GO项目实战之Gorm格式化时间字段实现的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • golang操作Redis的实现示例

    golang操作Redis的实现示例

    本文主要介绍了golang操作Redis的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-04-04
  • Go 语言中映射(Map)使用场景小结

    Go 语言中映射(Map)使用场景小结

    本文介绍了Go语言中映射(Map)的多种应用场景,包括基础的键值存储、集合实现、处理非结构化数据、数据分组、缓存优化和倒排索引等,感兴趣的可以了解一下
    2025-10-10
  • 一文掌握Golang的panic和recover实战

    一文掌握Golang的panic和recover实战

    Go语言中,异常处理通常依赖error返回值,本文将通过示例展示如何在Go语言中正确使用recover来处理panic异常,防止程序直接崩溃,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • Go1.18新特性工作区模糊测试及泛型的使用详解

    Go1.18新特性工作区模糊测试及泛型的使用详解

    这篇文章主要为大家介绍了Go 1.18新特性中的工作区 模糊测试 泛型使用进行详细讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Golang实现秒读32GB大文件示例步骤

    Golang实现秒读32GB大文件示例步骤

    这篇文章主要为大家介绍了Golang实现秒读32GB大文件的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • go语言中的udp协议及TCP通讯实现示例

    go语言中的udp协议及TCP通讯实现示例

    这篇文章主要为大家介绍了go语言中的udp协议及TCP通讯的实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Go数据结构之映射map方式

    Go数据结构之映射map方式

    这篇文章主要介绍了Go数据结构之映射map方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • 多阶段构建优化Go 程序Docker镜像

    多阶段构建优化Go 程序Docker镜像

    这篇文章主要为大家介绍了多阶段构建优化Go 程序Docker镜像,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08

最新评论