Python 二分法递归查找列表 v1.0

对于任意给定的实数数组,可以排序(从小到大排列)并实现任意目标的查找,若目标不在数组中,则返回其加入数组但不改变排序的索引值。

新手一枚,不足之处,敬请赞之→ _ →

解题思路

1.简单说二分查找就是一个切片查找的过程,通过对比目标(t)和中点值(m)[0]的大小决定是下一级查找是向左还是向右。例如:原数组[a,b, …, m-1,m,m+1,c,…,d],若t>m,则在1级数组[m+1,c, … ,d]中继续找中点,比大小,定左右,如此递归(为加快搜索进度,这里舍弃了中点值)。
[0]:中点值(m)的索引通过数组的端点(left和right)的索引和/2取整获得:
m=int((left+right)/2)

2.一般可以定位目标的切片长度(l)为1或2:
l=1,的上级切片长度为3,形如:[a,b,c],此时m=b,对比t和b的大小,切片即剩下[a]或[b];
l=2,的切片形如:[a,b],此时m=a,此时t可以在3个位置,若t<a,下级切片长度即为-1,此时有:
left=a(的索引),right=m-1=a-1
而此时t已经定位,t(的索引)=m(的索引)
若a<t<b,则t>a=m, left=m+1=b=right, 下级切片长度为1,t=m
若t>b,则t>a=m,left=m+1=b=right,下级切片长度为1,t=m+1。

3.综上,结束递归的条件可以分为3类:
1、t=m,返回中点索引;
2、切片长度为±1,通过比较t和m,返回中点索引或中点索引+1;
3、递归出错,返回None(因为当切片长度为-1时,L=R+1=m+1,若递归继续将进入死循环)。
由于切片操作会改变原数组,所以文章通过改变端点索引来定位中点索引,并且将中点索引对应的值命名为中点值[1]。

程序

def binary_search(thelist, target, right, left=0):
    '''binary search'''
    mid_index = int((left + right)/2)
    mid_value = thelist[mid_index]
    
    if left >= right:
       if target > mid_value:
           return mid_index+1
       else:
       	   return mid_index
    if target == mid_value:
        return mid_index
    elif target < mid_value:
        return binary_search(thelist, target, right=mid_index-1)
    else:
    	return binary_search(thelist, target, right, left=mid_index+1)

说明

(1)查找需要列表顺序排列,并初始化列表右端索引,如:

nums= [5, 6, 8, 90, 7, 1, 86, 31, 6, 9]
target = 80
nums.sort()
right = len(nums) - 1
result = binary_search(nums,target,right)

(2)递归错误的条件设置待定。
(3)若列表中有重复元素,返回内容待定。

上述问题已在2.0版中解决,详见:link1.
参考资料及问题来源:
[1] 本文方法参考了知乎《二分法查找的递归实现(python)》
链接:link2.
问题来源于贪心学院的“递归查找”一节。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值