''''''
'''
二分法查找-递归方法2-伪代码思路
1、递归方法1是每次递归调用,都新产生一个新的列表(长度减半)
2、递归方法1是每次递归调用,列表不变(不产生新的列表)
变动的是列表的左右边界-位置(每次递归调用,右边界和左边界下标的差就减少一半)
直到最后左右边界重合(找到了)
1、函数参数是4个
参数1:目标数
参数2:查找范围-列表
参数3:左边界位置-下标
参数4:右边界位置-下标
2、定义中位数
3、判断条件:左边界小于等于右边界 注意:等于不能遗漏
4、判断目标数和中位数的大小
1、目标数大于中位数
左边界变动到中位数位置+1
2、目标数小于中位数
右边界变动到中位数位置-1
3、目标数等于中位数
找到了,返回True
4、递归调用自己(参数:目标数、列表、左边界、右边界)
每次递归,左右边界都变动了
右边界和左边界下标的差每次递归减少一半
5、如果左边界大于右边界
没有找到,返回False
'''
def recursion2(n,li2,left,right):
#参数1:目标数
#参数2:查找范围-列表
#参数3:左边界位置
#参数4:右边界位置
if left <= right: #1 左边界位置小于等于右边界位置 #注意1:等于 不能遗漏
mid = (left + right) // 2 # 2 取中位数的位置 #注意2:用整除,而不是除号 位置是整数
if n < li2[mid]: #5 如果目标数小于中位数
right = mid - 1 #右边界位置改变到中位数位置-1
elif n > li2[mid]: #6 如果目标数大于中位数
left = mid + 1 #左边界位置改变到中位数+1
else: #7 如果目标数等于中位数
print('%s 找到了' % n) #找到了,返回True
return True
return recursion2(n,li2,left,right) #递归入口,每次递归调用,左右边界的位置都变了
#注意点3:前面必须加上return,才会实现第5次递归调用的返回值,依次传到了第一次递归调用
#如果没有加上return,第5次递归调用的返回值会给到第4次递归调用,而不会依次传递到第一次递归调用
#函数最后返回值取的是第一次递归调用
else: #3 如果左边界大于右边界
print('%s 没有找到' % n) #4 没有找到,目标数不在列表-查找范围中
return False
n=4
li2 = [1,2,3,4,5,6]
left = 0 #定义左边界的初始值
right = len(li2) -1 #定义右边界的初始值
recursion2(n,li2,left,right)
print('--------------------------1 递归方法2 改变左右边界的位置')
# def recursion3(n,li2,left=0,right=-1):
def recursion3(n,li2,left=0,right=len(li2)-1):
# if right == -1: #条件判断,如果右边界取默认值-1
# #注意点4:这么做的原因是,形参列表写入right=len(li2)-1可能不行,当然这里是可以的
# 如果形参列表不允许直接写类似len(li2)-1 就可以用这个方式,一个新的思路
# right = len(li2)-1 #就把右边界置为初始值 len(li2)-1
#参数1:目标数
#参数2:查找范围-列表
#参数3:左边界位置 用的是默认参数 左边界初始值是0
#参数4:右边界位置 用的是默认参数 右边界初始值设置成-1 然后修改
if left <= right: #1 左边界位置小于等于右边界位置 #注意1:等于 不能遗漏
mid = (left + right) // 2 # 2 取中位数的位置 #注意2:用整除,而不是除号 位置是整数
if n < li2[mid]: #5 如果目标数小于中位数
right = mid - 1 #右边界位置改变到中位数位置-1
elif n > li2[mid]: #6 如果目标数大于中位数
left = mid + 1 #左边界位置改变到中位数+1
else: #7 如果目标数等于中位数
print('%s 找到了' % n) #找到了,返回True
return True
return recursion2(n,li2,left,right) #递归入口,每次递归调用,左右边界的位置都变了
#注意点3:前面必须加上return,才会实现第5次递归调用的返回值,依次传到了第一次递归调用
#如果没有加上return,第5次递归调用的返回值会给到第4次递归调用,而不会依次传递到第一次递归调用
#函数最后返回值取的是第一次递归调用
else: #3 如果左边界大于右边界
print('%s 没有找到' % n) #4 没有找到,目标数不在列表-查找范围中
return False
n=5
li2 = [1,2,3,4,5,6]
# left = 0 #定义左边界的初始值
# right = len(li2) -1 #定义右边界的初始值
recursion3(n,li2,left,right)
print('--------------------------2 默认参数1 递归方法2 改变左右边界的位置')
def recursion4(n,li2,left=0,right=-1):
# def recursion4(n,li2,left=0,right=len(li2)-1):
if right == -1: #条件判断,如果右边界取默认值-1
#注意点4:这么做的原因是,形参列表写入right=len(li2)-1可能不行,当然这里是可以的
# 如果形参列表不允许直接写类似len(li2)-1 就可以用这个方式,一个新的思路
right = len(li2)-1 #就把右边界置为初始值 len(li2)-1
#参数1:目标数
#参数2:查找范围-列表
#参数3:左边界位置 用的是默认参数 左边界初始值是0
#参数4:右边界位置 用的是默认参数 右边界初始值设置成-1 然后修改
if left <= right: #1 左边界位置小于等于右边界位置 #注意1:等于 不能遗漏
mid = (left + right) // 2 # 2 取中位数的位置 #注意2:用整除,而不是除号 位置是整数
if n < li2[mid]: #5 如果目标数小于中位数
right = mid - 1 #右边界位置改变到中位数位置-1
elif n > li2[mid]: #6 如果目标数大于中位数
left = mid + 1 #左边界位置改变到中位数+1
else: #7 如果目标数等于中位数
print('%s 找到了' % n) #找到了,返回True
return True
return recursion2(n,li2,left,right) #递归入口,每次递归调用,左右边界的位置都变了
#注意点3:前面必须加上return,才会实现第5次递归调用的返回值,依次传到了第一次递归调用
#如果没有加上return,第5次递归调用的返回值会给到第4次递归调用,而不会依次传递到第一次递归调用
#函数最后返回值取的是第一次递归调用
else: #3 如果左边界大于右边界
print('%s 没有找到' % n) #4 没有找到,目标数不在列表-查找范围中
return False
n=6
li2 = [1,2,3,4,5,6]
# left = 0 #定义左边界的初始值
# right = len(li2) -1 #定义右边界的初始值
recursion4(n,li2,left,right)
print('--------------------------3 默认参数2 递归方法2 改变左右边界的位置')
'''
二分法查找小结
方法1:循环--每次循环,左右边界位置都会变化,两者之差减半
方法2:递归1-每次递归都产生一个新列表,长度是之前列表减半
方法3:递归2-每次递归,左右边界位置都会变化,两者之差减半
'''