真不愧是神算诸葛亮啊,猜数字背后竟然蕴含着这么神奇的算法(40)

小朋友们好,大朋友们好!

我是猫妹,一名爱上Python编程的小学生。

欢迎和猫妹一起,趣味学Python。

今日主题

猫妹最近不是在学习《人工智能编程实践Python5级》吗?

这里面除了基本的Python知识外,还有几章是介绍算法的。

算法,对猫妹来说是陌生的,毕竟刚接触嘛!

但是,算法在计算机中是非常重要的,可以说是人类智慧的结晶。

所以呢,这些很重要很基础的算法,猫妹决定简单记录下。

还记得高斯小时候的故事吗?

求计算1+2+。。。+100的和。

如果一个一个加,当然可以,但容易出错,而且非常耗费时间。

如果按照高斯的方法呢?

简单,而且不容易出错。

这就是算法,同一个问题,不同的解题思路。

有的算法效率高,有的算法效率低。

有的算法容易理解,有的算法思路实在是高。

猫爸小时候,还是个小学生,90年代。

有一次临近春节,他的玩伴和他做了一个游戏,让他心中藏一个数字,1000之内的整数。

他只问几个问题,猫爸只需要回答是或者不是,他就能猜出数字。

猫爸一开始觉得不可能,但是他的好友的确几次都猜对了。

猫爸觉得挺神奇的,但是不知道咋回事。

他的问题就是将数的范围逐渐缩小,每次缩小一半,也每次靠近猫爸心中的那个数。

这其实就是诸葛亮猜数字的故事。

诸葛亮召集将士,让他们从1-1024中选出一个整数记在心里。然后诸葛亮会问他们10个问题,他们只需回答:“是”或“不是”,最终诸葛亮就能得出他们心中所想的数。

如问一谋士:“你选的数大于512?”谋士答:“不是”,之后9个问题过后,诸葛亮得出谋士所选的数是1,谋士大为吃惊,这的确是他想的数。

方法就是把1024一半一半地取,取到第十次时就是1。根据这个原理去提10个问题就能找到别人心中所想的数。

这里面蕴含的算法就是二分法。

什么是二分法

二分法是一种计算机算法,也称为折半搜索或者二分搜索法。

它是一种在有序集合中查找特定值的算法。

该算法是通过将有序集合不断地二分为两半来实现的,从而查找到所需的元素。

简而言之,它是一种减少搜索区域的方法,从而使得搜索时间更快。

二分法思想

二分法是一种高效的搜索算法,适用于有序数据集的查找。

二分法的思想是不断将搜索区域二分为两个部分,直到找到目标元素或者搜索区域为空。

其基本思想是将待查找区间不断缩小一半,直到找到目标元素或者确定目标元素不存在。

具体步骤如下:

1)首先,找到列表的中间元素。

2)如果中间元素是目标元素,则停止搜索。

3)如果目标元素比中间元素小,则在中间元素的左边继续搜索。

4)如果目标元素比中间元素大,则在中间元素的右边继续搜索。

5)重复以上步骤,直到找到目标元素或者搜索区域为空。

二分法的时间复杂度

二分查找对有序列表的时间复杂度是 O(log n),其中 n 是列表的长度。

相对于线性搜索,二分查找效率更高,特别是当搜索区域比较大的时候。

二分法举例

Python语言非常适合实现二分法算法,其实现代码非常简单。

参考程序如下:

def binary_search(arr, low, high, target):    if high >= low:        mid = (high + low) // 2
        #如果目标元素等于中间元素,则找到了目标元素        if arr[mid] == target:            return mid        #如果目标元素比中间元素小,则在左边继续查找        elif arr[mid] > target:            return binary_search(arr, low, mid - 1, target)        #如果目标元素比中间元素大,则在右边继续查找        else:            return binary_search(arr, mid + 1, high, target)
    else:#元素不存在于数组中        return -1
if __name__ == '__main__':    arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]    target = 5    result = binary_search(arr, 0, len(arr)-1, target)    if result != -1:        print(f"元素在索引为 {result} 的位置")    else:        print("元素不在数组中")

我们首先定义一个`binary_search()`函数,该函数采用递归的方式实现二分查找。

参数`arr`是一个有序数组,参数`low`和参数`high`是数组中的两个索引,分别表示最低索引和最高索引。

参数`target`是要查找的元素。

在`binary_search()`函数中,先判断是否达到基准情况(即`high >= low`),如果已经到达基准情况,再判断目标元素是否等于中间元素(这里的中间元素是通过`mid`索引获得的)。如果目标元素等于中间元素,则返回中间元素的索引。

如果目标元素比中间元素小,则递归地查找左半边。

如果目标元素比中间元素大,则递归地查找右半边。

最后,我们以一个有序数组`arr`和要查找的元素`target`调用`binary_search()`函数。

如果函数返回的结果不为-1,则说明目标元素在数组中,打印该元素的索引值;否则,打印该元素不存在数组中。

我们看到,对于有序数组,二分查找比线性查找具有更好的时间复杂度。

当数组规模较大时,二分查找的时间复杂度更比线性查找的时间复杂度快很多。 

如果要在一个有序数组或列表中查找元素,应优先考虑使用二分查找算法。

好了,我们今天就学到这里吧!

如果遇到什么问题,咱们多多交流,共同解决。

我是猫妹,咱们下次见!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值