需求
# 需求:有一个按照从小到大顺序排列的数字列表
# 需要从该数字列表中找到我们想要的那一个数字
# 如何做更高效?
nums = [-3,4,7,10,21,43,77,89]
find_num = 77 # 代表本次要查找的数字
常规方法
# 需求:有一个按照从小到大顺序排列的数字列表
# 需要从该数字列表中找到我们想要的那一个数字
# 如何做更高效?
nums = [-3,4,7,10,21,43,77,89]
find_num = 77 # 代表本次要查找的数字
count = 1
for i in nums:
if i == find_num:
print("找到了,查找次数为:{}次".format(count))
break
count += 1
else:
print("没找到,共查找了:{}次".format(count))
# 平常的做法,只能靠运气来找。如果被排列的数值在整个列表的后面,刚好列表又十分庞大,
# 那么花费的时间是非常久的。
# ==== 执行结果 ====
"""
找到了,查找次数为:7次
"""
while循环实现二分法
# 需求:有一个按照从小到大顺序排列的数字列表
# 需要从该数字列表中找到我们想要的那一个数字
# 如何做更高效?
nums = [-3, 4, 7, 10, 21, 43, 77, 89]
find_num = 77 # 代表本次要查找的数字
left = 0
right = len(nums) - 1 # 代表列表索引范围
count = 1
while (left <= right):
mid = (left+right) // 2 # 代表列表中间索引
if find_num < nums[mid]:
right = mid - 1
elif find_num > nums[mid]:
left = mid + 1
elif find_num == nums[mid]:
print("找到了,查找次数为:{}次".format(count))
break
else:
print("没找到,查找次数为:{}次".format(count))
count += 1
# ==== 执行结果 ====
"""
找到了,查找次数为:3次
"""
递归实现二分法
# 需求:有一个按照从小到大顺序排列的数字列表
# 需要从该数字列表中找到我们想要的那一个数字
# 如何做更高效?
nums = [-3, 4, 7, 10, 21, 43, 77, 89]
find_num = 77 # 代表本次要查找的数字
count = 1
def binary_search(find_num, li):
global count # 传入计数器
count += 1
if not len(li): # 判断新切分的列表长度
print("没找到,查找次数为:{}次".format(count))
return
li.sort() # 进行排序
mid_index = len(li) // 2
mid_val = li[mid_index]
if find_num > mid_val:
new_l = li[mid_index+1:]
res = binary_search(find_num, new_l)
return res # 由于是递归,所以地推阶段时要每一层都返回
elif find_num < mid_val:
new_l = li[:mid_index]
res = binary_search(find_num, new_l)
return res
else:
print("找到了,查找次数为:{}次".format(count))
return find_num
binary_search(find_num, nums)
# 二分法,传入的列表必须是有序的。每次查找都先拿到中间值,
# 判断中间值与查找值的大小。如果查找值较大则切分右边列表,继续拿中间值
# 重复比较步骤...
# ==== 执行结果 ====
"""
找到了,查找次数为:3次
"""
二分法图解
