算法初步:二分查找

Posted 芒果编程工作室

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法初步:二分查找相关的知识,希望对你有一定的参考价值。



问题

给你一串排好序(升序)的数字和一个目标数字,如何找到该目标数字在这串数字中的第几位?(假设目标数字一定在这串数字中,而且没有重复的数字)



算法1

第一种方法,大家肯定想到了暴力解法,从第一位开始找,直到最后一个数字,找到了就直接返回。


这种算法的时间复杂度是O(n),属于线性级的复杂度,即数列的长度是多少,就要比对多少次,还能接受


代码实现

#!/usr/bin/python3
nums_str = input("请输入排序好的数列(以英文逗号隔开):")target_num = int(input("请输入目标值:"))nums_list = nums_str.split(',')
target_pos = 0#从头开始找for i in range(0, len(nums_list)): if int(nums_list[i]) == target_num: target_pos = i break
print("目标值在数列中的第%d位置" % (target_pos + 1))


执行结果





算法2

既然这些数字都是排好序的,那是不是可以先拿这串数字中间的那个数字和目标值比较呢?


如果相等,那最好,直接就找到了;

如果目标值大于中间数,说明目标值在中间数的右边,左边数字的都可以舍弃,不用比对;

如果目标值小于中间数,说明目标值在中间数的左边,右边的数字都可以舍弃,不用再比对了。


这样一步下来,基本就可以舍弃掉一半的数字不用再比对了,而且拿到了一个更小的范围区间。接下来再在这个范围区间里,重复这样的操作,直到找到了目标值为止。


这种算法的时间复杂度是O(log(n)),属于对数级的复杂度,比第一种算法的O(n)进步了很多

试想,如果这个数列的长度非常非常大,有一百万个数字,第一种算法就需要比对一百万次,而第二种算法只需要log₂1000000,约等于20。一个百万次比较,一个20次比较,哪个算法的效率高,应该很明了了。


这种算法,我们称之为二分查找法,也就是每一次操作后,都能舍弃掉一半的无效结果,只需要在另一半有效的结果里查找即可。


代码实现

#!/usr/bin/python3import math
nums_str = input("请输入排序好的数列(以英文逗号隔开):")target_num = int(input("请输入目标值:"))nums_list = nums_str.split(',')
# 区间左侧索引left = 0# 区间右侧索引right = len(nums_list) - 1while left < right: print("==========本次查找的范围是:", nums_list[left:right + 1]) middle = (left + right) // 2 middle_num = int(nums_list[middle]) print("中间的数字为:%d" % middle_num) if middle_num == target_num: break elif middle_num > target_num: print("%d>%d,所以再从%d的左侧比较" % (middle_num, target_num, middle_num)) right = middle - 1 else: print("%d<%d,所以再从%d的右侧比较" % (middle_num, target_num, middle_num)) left = middle + 1
target_pos = (left + right) // 2print("目标值在数列中的第%d位置" % (target_pos + 1))


执行结果

以上是关于算法初步:二分查找的主要内容,如果未能解决你的问题,请参考以下文章

算法初步--递归思想(java实现)

算法初步--递归思想(java实现)

算法初步--递归思想(java实现)

算法初步--递归思想(java实现)

PHP实现二分查找算法(代码详解)

「算法笔记」一文摸秃二分查找