# 在有序序列内查找,判断大于还是小于中间值,每次搜索减一半,直到达到退出条件
# 递归二分查找具体索引
def search(num, start, end, args):
global m
m += 1
middle = (start + end) // 2 # 整除取中间值
# print('start:%s , end:%s , middle:%s , args[middle]:%s' % (
# start, end, middle, args[middle]))
if num == args[middle]: # 判断是否匹配
return middle,m # 返回匹配索引
elif end == middle: # start == end or
return '未找到该值',m
elif num > args[middle]: # 判断所找值是否大于序列中间的值
# 在上面已经判断过了中间索引,所以下次要从中间索引+1位置开始,否则容易出现死循环
start = middle + 1
return search(num, start, end, args) # 继承上层的结束索引,改变开始索引
else: # 小于序列中间值
# 在上面已经判断过了中间索引,所以下次要从中间索引-1位置开始,否则容易出现死循环
end = middle - 1
return search(num, start, end, args) # 继承上层的开始索引,改变结束索引
# 循环二分查找索引,返回索引和次数
def search2(num, args):
start = 0 # 首索引
end = len(args) - 1 # 尾索引
middle = (start + end) // 2
m = 0
while num != args[middle]: # 不等于就继续找
m += 1
if end == middle:
return '未找到 %s' % num, m
elif num > args[middle]:
start = middle + 1
else:
end = middle - 1
middle = (start + end) // 2
else:
return middle, m
lis = list(range(1, 10100002, 4))
m = 0 # 计次
num = 10100001 # 查找值
if num <= lis[len(lis) - 1]:
# print(lis)
# ret = search(num, 0, len(lis) - 1, lis)
# print('查找值: %s ,索引: %s ,共找了: %s 次' % (num, ret, m))
ret = search(num-4, 0, len(lis), lis)
print('查找值: %s ,索引: %s ,共找了: %d 次' % (num-4, *ret))
ret = search2(num, lis)
print('查找值: %s ,索引: %s ,共找了: %d 次' % (num, *ret))
else:
print('数字超过范围')
# 递归切片二分查找是否存在序列里
def search3(num, nums):
middle = len(nums) // 2
if len(nums) < 1: # 序列为空说明找完了
return False
if num == nums[middle]:
return True
elif num > nums[middle]:
return search3(num, nums[middle + 1:])
else:
return search3(num, nums[:middle]) # 切片结束位置是middle的前一个位置,所以不用再减一
# 循环切片二分查找是否存在序列里
def search4(num, nums):
while len(nums) > 0:
middle = len(nums) // 2
if num == nums[middle]:
return True
elif num > nums[middle]:
nums = nums[middle + 1:]
else:
nums = nums[:middle] # 切片结束位置是middle的前一个位置,所以不用再减一
else:
return False
lis = list(range(1, 10100002, 4))
print(search3(2, lis))
print(search4(10100001, lis))