python之协程函数、递归、二分法

本文介绍了协程函数的概念及使用方法,并详细解释了递归调用的特点与注意事项。此外,还简要提及了面向过程的优缺点以及二分查找算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、协程函数:

    协程函数的语法:

    def eater(name):

            print('%s说:我开动啦' %name)
food_list=[]
while True:
food=yield food_list
food_list.append(food)
print('%s 吃了 %s' %(name,food))

e=eater('egon')
e.send(None) #next(e) #初始化装饰器,
e.close() #关闭
    解决方法:第一步:初始化函数Next(),第二部:给yield传值
二、面向过程:
    面向过程:核心是过程二字,过程就是解决问题的步骤,
基于面向过程去设计程序就像是在设计,一条工业流水线,是一种机械式的思维方式    #优点:程序结构清晰,可以把复杂的问题简单化,流程化
    #缺点:可扩展性差,一条流线只是用来解决一个问题
    #应用场景:linux内核,git,httpd,shell脚本
三、递归:
  
  递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身

    递归效率低,需要在进入下一次递归时保留当前的状态
   解决方法是尾递归,即在函数的最后一步(而非最后一行)调用自己
   但是python又没有尾递归,且对递归层级做了限制

  1. 必须有一个明确的结束条件

  2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

  3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,              栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)



  递归的执行分为两个阶段:
  1 递推
  2 回溯
  
def age(n):

   if n == 1:
          return 18
   return age(n-1)+2
     print(age(5))


四、二分法:
    
l=[1,2,10,2,30,40,33,22,99,31]
        def search(num,l):
print(l)
if len(l) > 1:
mid=len(l)//2
if num > l[mid]:
#in the right
l=l[mid:]
search(num,l)
elif num < l[mid]:
#in the left
l=l[:mid]
search(num,l)
else:
print('find it')
else:
if num == l[0]:
print('find it')
else:
print('not exists')

search(100,l)
 
 

 

 

 
 

  

转载于:https://www.cnblogs.com/MouseCat/p/7266537.html

<think>嗯,用户现在问的是如何用Python递归方法来实现二分法。首先,我需要确定用户对二分法的理解程度。二分法通常用于在有序数组中查找目标值,或者用于求解方程的近似解。不过这里用户没有具体说明是哪一种,但结合上下文,可能更偏向于查找算法,因为之前提到了递归Python实现。 用户之前的问题是关于递归中初始值的传递,现在转向递归实现二分法,可能需要将之前的递归结构与二分法结合起来。首先,我应该回顾二分法的基本步骤:确定中间位置,比较中间元素与目标值,根据比较结果调整搜索范围为左半部分或右半部分,递归直到找到目标或范围为空。 然后,我需要考虑如何用递归来实现这个过程。递归函数需要接收当前搜索范围的左右边界参数,每次递归调用时调整这些边界。初始值的传入,比如左右边界的起始值(通常是0和len(arr)-1),这点可能和之前的问题相关,用户可能想知道如何正确传递这些初始参数。 接下来,我需要确保递归终止条件的正确性。对于二分法来说,终止条件应该是当左边界超过右边界时,说明元素不存在,返回-1或其他指示值。另外,在每次递归中需要计算中间索引,避免整数溢出的问题,不过在Python中整数可以很大,所以可能不需要特别处理,但通常写法是mid = (left + right) // 2。 然后,用户可能需要一个示例代码来理解具体实现。代码的结构应该是定义一个递归函数,参数包括数组、目标值、左右边界,默认参数设为0和None,然后在函数内部处理初始边界的设置。比如,当第一次调用时,右边界为None,可以设置为len(arr)-1。 需要检查代码是否正确处理了各种情况,比如目标值等于中间元素,小于或大于的情况,分别递归左半部分或右半部分。同时,要确保递归调用时参数正确传递,比如左边界调整为mid+1或右边界调整为mid-1。 另外,用户可能对递归的效率和栈深度有疑问,但Python递归深度默认有限制,对于非常大的数组可能导致栈溢出。不过这可能超出当前问题的范围,用户可能只需要基础实现。 最后,应该提供测试用例,比如一个有序数组,查找存在和不存在的情况,验证代码的正确性。同时,解释递归调用的过程和每次参数的变化,帮助用户理解初始值如何传递,中间步骤如何缩小搜索范围。 可能的误区包括中间索引的计算错误,或者递归调用时边界调整不当导致无限循环。需要强调正确调整边界的重要性,以及终止条件的必要性。此外,默认参数的使用可能会让用户在初次调用时更方便,不需要显式传递左右边界。 总结起来,回答的结构应该包括二分法的原理,递归实现的步骤,代码示例及解释,测试案例,以及可能的注意事项。这样用户不仅能得到代码,还能理解背后的逻辑和实现细节。</think>--- ### **递归实现二分法的原理与步骤** 二分法的核心思想是**通过不断缩小搜索范围,快速定位目标值**,适用于**有序数组**的查找问题。递归实现的关键在于**将大问题分解为子问题,并通过参数传递缩小搜索区间**。 --- ### **Python递归实现代码** ```python def binary_search_recursive(arr, target, left=0, right=None): # 初始化右边界(首次调用时设置) if right is None: right = len(arr) - 1 # 递归终止条件:区间无效 if left > right: return -1 # 未找到 mid = (left + right) // 2 # 计算中间索引 if arr[mid] == target: return mid # 找到目标,返回索引 elif arr[mid] < target: # 目标在右半区,调整左边界为 mid+1 return binary_search_recursive(arr, target, mid + 1, right) else: # 目标在左半区,调整右边界为 mid-1 return binary_search_recursive(arr, target, left, mid - 1) ``` --- ### **代码解析** #### **1. 参数设计** - `arr`: 有序数组(必须升序排列) - `target`: 待查找的目标值 - `left`: 当前搜索区间的左边界(初始为0) - `right`: 当前搜索区间的右边界(首次调用时自动设为数组末尾索引) #### **2. 递归终止条件** - **区间无效**(`left > right`):说明目标不存在,返回`-1` - **找到目标**(`arr[mid] == target`):返回当前中间索引`mid` #### **3. 递归缩小范围** - **目标在右半区**(`arr[mid] < target`):调整左边界为`mid + 1` - **目标在左半区**(`arr[mid] > target`):调整右边界为`mid - 1` --- ### **执行过程示例** 假设数组为 `[2, 5, 8, 12, 16, 23, 38, 56]`,查找`23`: 1. **初始调用**:`binary_search_recursive(arr, 23)` → `left=0`, `right=7` - `mid=(0+7)//2=3` → `arr[3]=12 < 23` → **递归右半区** `left=4` 2. **第2层递归**:`left=4`, `right=7` - `mid=(4+7)//2=5` → `arr[5]=23 == 23` → **返回索引5** --- ### **关键特性对比** | 特性 | 递归实现 | 循环实现 | |---------------------|--------------------------------------|--------------------------------------| | **空间复杂度** | $O(\log n)$(递归栈深度) | $O(1)$ | | **代码可读性** | 更符合“分治”直观逻辑 | 需手动维护边界变量 | | **适用场景** | 数据规模较小(避免栈溢出) | 数据规模较大 | --- ### **常见问题解答** #### **1. 为什么必须是有序数组?** 二分法的核心依赖**有序性**。若数组无序,无法通过中间值判断目标所在区间,算法失效。 #### **2. 如何处理重复元素?** - 若需返回第一个匹配项:找到目标后继续向左半区搜索。 - 若需返回最后一个匹配项:找到目标后继续向右半区搜索。 #### **3. 递归的终止条件如何确保正确性?** 通过严格缩小区间(`mid ±1`)确保每次递归区间缩小,最终触发`left > right`。 --- ### **扩展:测试用例** ```python arr = [2, 5, 8, 12, 16, 23, 38, 56] print(binary_search_recursive(arr, 23)) # 输出5(存在) print(binary_search_recursive(arr, 100)) # 输出-1(不存在) ``` --- ### **总结** 递归实现二分法通过**参数传递区间边界**和**逐层缩小范围**完成查找,代码简洁但需注意递归深度限制。关键点在于: 1. **正确计算中间索引** 2. **合理调整区间边界** 3. **明确终止条件**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值