算法设计与分析作业(一)实现几种不同情形的二分查找

这篇博客详细介绍了如何实现六种不同情况的二分查找算法,包括找到等于、大于、小于、大于等于、小于等于目标值的最小或最大索引。通过具体的输入输出示例,展示了算法的应用,并提出了在随机数据中寻找最大值和最小值的高效算法以及统计比较次数的方法。

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

 实现几种不同情形的二分查找。

 

1). 求等于x的最小的index,不存在返回-1。

输入:

3  5  5  7  7  10  11  12  

0  7  7

输出:

3

输入说明:

一组整形数组:3  5  5  7  7  10  11  12

查找的范围为:数组第0个元素至第7个元素

查找的元素为:7

 

2). 求等于x的最大的index,不存在返回-1。

输入:

3  5  5  7  7  10  11  12  

0  7  7

输出:

4

输入说明:

一组整形数组:3  5  5  7  7  10  11  12

查找的范围为:数组第0个元素至第7个元素

查找的元素为:7

 

3). 求小于x的最大的index。

输入:

3  5  5  7  7  10  11  12  

0  7  8

输出:

    4

输入说明:

一组整形数组:3  5  5  7  7  10  11  12

查找的范围为:数组第0个元素至第7个元素

<
### 二分查找的分治算法实现原理 #### 原理概述 二分查找种典型的分治算法,其核心思想是通过不断将待查区间划分为两部分,从而逐步缩小搜索范围。这种方法适用于已经排序好的数据集合,在每次迭代或递归过程中,选取当前区间的中间位置作为参照点,并将其目标值进行比较。如果匹配成功,则立即返回结果;如果不匹配,则依据大小关系决定继续在左侧还是右侧子区间重复这过程[^1]。 具体来说,当给定一个升序排列的数据序列`A[low..high]`以及要查询的目标值`target`时: - 首先计算出该区间的中点索引 `mid = floor((low + high)/2)`; - 接着判断位于此位置上的元素 A[mid]: - 若恰好等于 target ,则找到所需项并终止操作; - 如果它小于 target 则说明所求值必定存在于右半段 `[mid+1 .. high]` 中; - 反之若大于 target 则转而在左半段 `[low ... mid-1]` 继续寻找。 整个流程持续执行直至剩余未处理的部分长度降为零为止 —— 即 low>high 的情况表明不存在满足条件的对象存在于此列表之中[^5]。 #### 实现方式 以下是基于Python语言描述的一个标准非递归形式下的二分查找函数定义: ```python def binary_search(arr, target): """ 使用二分查找定位数组中的某个整数 参数: arr (list): 已经按从小到大顺序排好序的输入数组. target (int): 被检索的具体数值. 返回: int: 找到了就给出对应下标; 否则输出 -1 表明失败. """ left, right = 0, len(arr)-1 while left <= right : mid = (left + right)//2 if arr[mid]==target : return mid # 成功发现相等情形 elif arr[mid]<target : left=mid+1 # 更新起点至更高区域 else: right=mid-1 # 移动终点至更低领域 return -1 # 结束循环意味着无果而终 ``` 另外还有种利用递归来表达相同逻辑的方式如下所示 : ```python def recursive_binary_search(array, value_to_find, start_index=None, end_index=None): """Recursively performs a binary search on the given sorted array.""" if not isinstance(array,(tuple,list)): raise TypeError('First argument must be an iterable like list or tuple.') length=len(array) if None==start_index and None==end_index: start_index,end_index=(0,length-1) midpoint=start_index+(end_index-start_index)//2 if(start_index<=end_index): current_element=array[midpoint] if(current_element<value_to_find): new_start_index=midpoint+1 result=recursive_binary_search(array,value_to_find,new_start_index,end_index) elif(value_to_find<current_element): new_end_index=midpoint-1 result=recursive_binary_search(array,value_to_find,start_index,new_end_index) else:#found it! result=midpoint else: result=-1 return result ``` 以上两种方法本质上并无区别,只是表现手法有所差异而已。前者更加直观易懂且效率较高因为避免了额外栈空间开销;后者虽然相对复杂些但对于理解递归机制很有帮助[^4]。 ### 注意事项 尽管二分查找非常高效(O(log n)),但在实际运用当中需要注意几点前提假设才能保证正确性和性能优势最大化: - 输入数据集必须事先经过严格单调增/减次序整理完毕之后才可以调用此类技术手段去解决问题[^3]. - 数据结构支持随机访问特性(Random Access),比如数组或者向量容器类型最为理想适合场景应用需求[^2].
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值