有序清单里某个数值可能出现不止一次。找到任意一个匹配位置还不足以确定全部结果,分别找第一个不小于目标与第一个大于目标的位置,才能得到完整半开区间。
规则与边界
数组从小到大排列,搜索范围用左闭右开的区间表示。下界搜索遇到中点值小于目标就移动左边界,否则移动右边界;上界搜索把前一条比较改成小于等于。每次中点取两边界之和除以二向下取整。
本例记录
排序后数组为[0, 3, 6, 6, 6, 7, 8, 8, 8, 10, 12, 12, 13, 13, 14, 14, 14, 17, 17, 19, 20, 22, 27, 29],长度24。下列每步记录左边界、右边界、中点和中点值。
目标-1:下界过程[[0, 24, 12, 13], [0, 12, 6, 8], [0, 6, 3, 6], [0, 3, 1, 3], [0, 1, 0, 0]];上界过程[[0, 24, 12, 13], [0, 12, 6, 8], [0, 6, 3, 6], [0, 3, 1, 3], [0, 1, 0, 0]];匹配区间[0,0),数量0。 目标31:下界过程[[0, 24, 12, 13], [13, 24, 18, 17], [19, 24, 21, 22], [22, 24, 23, 29]];上界过程[[0, 24, 12, 13], [13, 24, 18, 17], [19, 24, 21, 22], [22, 24, 23, 29]];匹配区间[24,24),数量0。 目标6:下界过程[[0, 24, 12, 13], [0, 12, 6, 8], [0, 6, 3, 6], [0, 3, 1, 3], [2, 3, 2, 6]];上界过程[[0, 24, 12, 13], [0, 12, 6, 8], [0, 6, 3, 6], [4, 6, 5, 7], [4, 5, 4, 6]];匹配区间[2,5),数量3。 目标17:下界过程[[0, 24, 12, 13], [13, 24, 18, 17], [13, 18, 15, 14], [16, 18, 17, 17], [16, 17, 16, 14]];上界过程[[0, 24, 12, 13], [13, 24, 18, 17], [19, 24, 21, 22], [19, 21, 20, 20], [19, 20, 19, 19]];匹配区间[17,19),数量2。 目标29:下界过程[[0, 24, 12, 13], [13, 24, 18, 17], [19, 24, 21, 22], [22, 24, 23, 29], [22, 23, 22, 27]];上界过程[[0, 24, 12, 13], [13, 24, 18, 17], [19, 24, 21, 22], [22, 24, 23, 29]];匹配区间[23,24),数量1。 目标6:下界过程[[0, 24, 12, 13], [0, 12, 6, 8], [0, 6, 3, 6], [0, 3, 1, 3], [2, 3, 2, 6]];上界过程[[0, 24, 12, 13], [0, 12, 6, 8], [0, 6, 3, 6], [4, 6, 5, 7], [4, 5, 4, 6]];匹配区间[2,5),数量3。 目标2:下界过程[[0, 24, 12, 13], [0, 12, 6, 8], [0, 6, 3, 6], [0, 3, 1, 3], [0, 1, 0, 0]];上界过程[[0, 24, 12, 13], [0, 12, 6, 8], [0, 6, 3, 6], [0, 3, 1, 3], [0, 1, 0, 0]];匹配区间[1,1),数量0。 目标25:下界过程[[0, 24, 12, 13], [13, 24, 18, 17], [19, 24, 21, 22], [22, 24, 23, 29], [22, 23, 22, 27]];上界过程[[0, 24, 12, 13], [13, 24, 18, 17], [19, 24, 21, 22], [22, 24, 23, 29], [22, 23, 22, 27]];匹配区间[22,22),数量0。
表中编号只标记本例对象,不表示排名或另一组数据中的身份。先确认输入单位与边界约定,再逐步核对中间值。零、空结果和不存在是不同状态,不能因为显示相近就互相替代;分数用精确形式保留,便于重新演算。
复核方法
两个搜索结束时左右边界重合。匹配元素位于下界至上界之前,数量为两者之差;数量为零说明目标不存在,不能把返回的插入位置直接拿来读取元素。目标大于所有元素时,边界可以等于数组长度。
用线性扫描独立核对结果:下界前的值都小于目标,上界后的值都大于目标,中间则全相等。练习时加入低于最小值、高于最大值和只出现一次的目标,确认边界处也能结束,避免在空区间反复取同一个中点。
能说明什么
二分搜索依赖整个数组按同一比较规则排序。中途修改数组或使用不一致的比较器,会破坏前提。这里比较普通整数,不涉及模糊匹配、大小写转换或显示文字与实际排序值不同的情况。
这份记录用于理解明确规则下的游戏机制。改变输入后,结果也应随之重新计算;若操作规则不同,应先把新规则写清再比较。可以从一两个步骤手算开始,找出第一处差异,而不是只对照最后一个数值。全部中间记录都属于当前案例,不能直接当成其他场景的固定答案。
