详析二分查找算法(两年开发小哥居然因为它被pass)

引言

今天陪同组长面试一位两年后端经验的开发小哥,开始面试前,看了一下小哥做的笔试题,回答的还可以。之后听了他的自我介绍,以及他对实际项目开发过程的阐述,也是比较清晰,于是可以判断他之前的工作经历是没有问题的。

接着,组长便开始对他进行技术提问,前面回答的都不错,看的出来,在这组长也是比较满意他。但接下来组长问了一个问题:给定一个数组,怎样在数组中寻找特定值?

只见小哥毫不犹豫的说出使用for循环,然后利用if语句来判断后,我心头顿时一紧(小哥的思路)

static int LinearSearch(int[] arr, int x)
    {
        for (int i = 0; i < arr.Length; i++)
        {
            if (arr[i] == x)
                return i; 
        }
        return -1; 
    }

小哥说完后,组长给了他机会,便又问道:“还有其他解决方式吗?”

显然小哥被组长这么一问,有些懵逼了,便又重新说道:“如果我们知道查找值在数据的位置,我们可以根据索引去获取具体值,毕竟数组有随机访问的特性…等等”

小哥说完后,组长便指引着询问:“你知道过二分查找吗?能讲一下其中原理?”

小哥被这样一问,更加懵逼了,一时不知道怎么回答…

后面小哥的结果我也就不描述了。

说了这么多,只想为大家强调一件事:基础算法很重要!基础算法很重要!基础算法很重要!重要的事情说三遍。

到这里,故事也就结束了,但我们的正题内容才刚刚开始!解下来,我将为大家介绍一下二分查找算法。

如果已经掌握了朋友,看到这里就可以离开了。但我还是希望你能再多看一眼,加深一下记忆也是挺好的。如果没有听说的朋友,那就请仔细学习一下,对你来说,将是百利而无一害,或许在不久的将来你就可能用上。

二分查找(Binary Search)

先来看一下定义:二分查找是一种在有序数组中查找元素的高效算法。它通过不断地将数组分成两半来缩小搜索范围,直到找到所需的元素或搜索范围为空。

注意,这有个极其重要的关键词:有序。如果这个条件缺少,二分查找就不能使用!所以基础排序算法的掌握也是极其重要的一个知识点,大家也应好好掌握。(额外话:这里也有一个萌妹子程序员的故事,如果大家感兴趣,我下期可以跟大家分享一下(^_^)

二分查找的工作原理

  1. 初始化范围:二分查找开始时,定义一个查找范围,该范围由数组的起始索引 low 和结束索引 high 决定。

  2. 计算中间点:在每次迭代中,计算当前范围的中间索引 mid,通常使用公式:

  1. 比较元素

    • 如果目标元素 x 等于 arr[mid],则直接返回 mid 作为目标元素的索引。
    • 如果目标元素 x 小于 arr[mid],则目标元素可能位于左半部分,因此将查找范围缩小为 lowmid-1
    • 如果目标元素 x 大于 arr[mid],则目标元素可能位于右半部分,因此将查找范围缩小为 mid+1high
  2. 重复过程:重复步骤2和3,直到找到目标元素或查找范围为空(即 low 大于 high),此时返回 -1,表示元素不在数组中。

二分查找的示例

 可能光讲概念,大家可能就有些晕了,并说到:“这都是讲的写什么啊。”所以,先别急着晕,我们来看一个例子,看完之后你就会觉得:“这也不过如此。”

假设我们有一个升序排列的数组 ,如上,我们要查找元素 4 的索引。

  1. 初始范围:low = 0, high = 8 (数组的索引范围)。
  2. 计算中间点:mid = 4,数组中的元素是 arr[4] = 7
    • 因为 4 < 7,我们知道目标元素在左半部分,调整范围:low = 0high = 3
  3. 再次计算中间点:mid = 1,数组中的元素是 arr[1] = 3
    • 因为 4 > 3,我们知道目标元素在右半部分,调整范围:low = 2high = 3
  4. 再次计算中间点:mid = 2,数组中的元素是 arr[2] = 4。找到目标元素,返回索引 3

二分查找的时间复杂度

二分查找的时间复杂度为 O(log n),因为每次查找操作都将查找范围减半。与线性查找的 O(n) 相比,二分查找在处理大规模数据时非常高效。

注意事项

  • 前提条件:二分查找要求数组必须是有序!有序!有序!这里我又说了三遍。
  • 元素重复:如果数组中存在多个相同的元素,二分查找可能不会返回第一个出现的元素的索引,而是找到的任意一个。

代码实现

static int binary_search(int[] arr, int start, int end, int key)
{
    int mid;
    while (start <= end)
    {
        mid = (start + end) / 2;
        if (arr[mid] < key)
            start = mid + 1;
        else if (arr[mid] > key)
            end = mid - 1;
        else
            return mid; 
    }
    return -1;
}

 结语

最后,二分查找常用于查找问题的基础算法,广泛应用于各种需要高效查找的场景中,也是面试的高频问题,希望有需要的小伙伴好好参考一下,如果有问题还望指正,大家共同进步!更希望这能帮助到你!(^_^)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值