二分法

本文探讨了二分法在计算机科学中的应用,特别是在算法和数据结构中的重要性。通过分析二分法的细节和常见问题,如中位数索引值的获取、循环条件设置及分支选择,揭示了算法设计的关键。文章还提到在Java和C语言中处理溢出和右移操作的注意事项,并提出改进的循环条件和避免死循环的策略。最后,文章提到了二分法与斐波那契搜索的关系,鼓励读者深入研究二分法的优化和应用场景。

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

2019年终记事:一年的经历那么多,回忆起来却短的不可想象。2019年的最后一篇博客,回想第一篇到现在,虽然一路上走走停停,但学习的脚步还在前进。短短二十年放弃的东西比一声叹息多多了,回头看来人生得要有一件能坚持下去的东西……新年的钟声带不走2019的遗憾,希望它能带来2020的希望。


引言

在计算机科学中,二分搜索,也称为半间隔搜索,对数搜索,是一种搜索算法,用于查找排序数组中目标值的位置。二分搜索将目标值与数组的中间元素进行比较。
如果它们不相等,则消除目标不能位于其中的那一半,并在剩余的一半上继续搜索,再次将中间元素与目标值进行比较,并重复此过程直到找到目标值。
如果搜索以其余一半为空结束,则目标不在数组中。
在最坏的情况下,二分搜索会以对数时间运行,进行 O ( log ⁡ n ) O(\log_{}n) O(logn)比较,其中 n {n} n是数组中元素的数量, O {O} O是Big O表示法, 而 log ⁡ {\log} log是对数。 除了小数组以外,二分搜索比线性搜索快。 但是,必须首先对数组进行排序才能应用二进制搜索。有专门为快速搜索而设计的专用数据结构,例如哈希表,可以比二进制搜索更有效地进行搜索。 但是,二分搜索可用于解决更广泛的问题,例如,即使数组中不存在目标,也要在数组中找到相对于目标而言第二小的元素。
二进制搜索树和B树数据结构基于二分搜索。
——wiki

在leetcode刷题时我们总能遇到可以利用二分搜索解决的问题,但往往我们写得出来的二分搜索代码并不能work或者潜藏有bug。造成这种现象的原因是纷杂的情况导致算法的细节处理不同而容易忽视边界的细节问题。我们需要一个简洁明了的思路来将问题一般化。矛盾的特殊性应该包含在矛盾的一般性当中,用高度抽象化的过程对具体问题降维打击。

编写博客时翻阅了不少leetcode中的二分题解,在此借鉴并总结一下。在完成的过程中翻阅了《计算机程序设计艺术》的相关章节,受益颇多,一部分内容会穿插在文中讲述。

入题

一些背景——

《计算机程序设计艺术》的作者 Donald Knuth:

Although the basic idea of binary search is comparatively straightforward, the details can be surprisingly tricky …

译:“虽然二分搜索的基本思想很直白,但细节出奇的难以应对…”

他在《计算机程序设计艺术(第三卷)》中也指出了(大意):也许是第一部出版的关于非数值程序设计方法的书(1946)中,首先提出了二分查找。再到后来的许多人对二分算法的改进直至60年代往后,所有工作才算是基本完成。

一些待解决的问题——

  1. 中位数索引值的获取
  2. 循环执行条件的设置与返回值的选择
  3. 分支语句的选择

关于模板——

这里借助Thomas H. Cormen在《算法基础–打开算法之门》中的一段伪代码:

程序   BINARY-SEARCH(A,n,x)

输入:
·A:一个数组;
·n:要查找的数组A中元素的个数;
·x:要查找的值;

输出:要么是满足A[i]=x的索引i,要么是一个特殊值 NOT-FOUND(可取相对数组A的任何无效索引值,例如0或任意负整数)。

//左右索性记为p,r;中间位置记为q

1. 将p赋值为1,将r赋值为n。
2. 只要p≤r,执行如下操作:
 		A. 将q赋值为⌊(p+r)/2⌋。
 		B. 如果A[q]=x,那么返回q。
 		C. 否则(A[q]≠x),如果A[q]>x,那么将r赋值为q-1。
 		D. 否则(A[q]<x),那么将p赋值为q+1。
3. 返回 NOT-FOUND。

这段算法描述是我们常规的理解和处理方法,这次打算讨论的是在它的基础上进行一定的改变,并简单谈谈优劣。

基本思想————

二分的基本思想其实就是每次可以将当前的数中将近一半的不满足要求的数全部除掉,所以大O时间复杂度是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值