二分探索
data/lecture/information/algorithm/search/linear-search.lecture.n.md
1導入
この講義では、昇順に整列された配列に対する二分探索を、探索区間の不変条件から説明する。線形探索は各要素を順次比較するが、二分探索は整列順序を利用して、一回の比較で候補区間の一方を除外する。
2問題設定
n\geq 0 要素の配列 A=(A_0,A_1,\ldots,A_{n-1}) が
A_0\leq A_1\leq\cdots\leq A_{n-1}
を満たす、すなわち昇順に整列されているとする。目標値 x に対して、A_i=x を満たす添字 i が存在すればその一つを返し、存在しなければ不在を返す。
重複要素を許容するため、x が複数の位置に存在する場合、この算法はそのうちいずれか一つの添字を返す。最初または最後の出現位置を求める仕様ではない。
3半開区間と中央
候補となる添字を半開区間 [l,r) で表す。この区間は l を含み、r を含まず、区間長は r-l である。l<r のとき、中央添字を
m=\left\lfloor\frac{l+r}{2}\right\rfloor
とする。このとき l\leq m<r が成立するため、A_m は現在の候補区間内に存在する。
4不変条件
反復の開始時点で、次の条件を維持する。
x が配列に存在するなら、A_i=x を満たす添字が [l,r) に存在する。
4.1初期化
初期値を l=0、r=n とする。候補区間 [0,n) は配列全体を含むため、不変条件が成立する。
4.2保存
l<r のもとで中央 m を計算し、A_m と x を比較する。
- A_m=x なら、m を返して終了する。
- x<A_m なら、昇順性により、すべての i\in[m,r) について A_i\geq A_m>x である。したがって [m,r) に一致位置はなく、r=m と更新できる。
- A_m<x なら、昇順性により、すべての i\in[l,m+1) について A_i\leq A_m<x である。したがって [l,m+1) に一致位置はなく、l=m+1 と更新できる。
いずれの更新でも、一致位置となり得る添字だけが新たな候補区間に残るため、不変条件は保存される。
4.3終了
l=r では候補区間が空である。不変条件により、x が存在するなら一致位置がこの空区間に存在するはずであり、これは不可能である。したがって x は配列に存在せず、不在を返してよい。
5停止性
更新前の区間長を L=r-l>0 とする。r=m の場合の新たな長さは m-l、l=m+1 の場合は r-m-1 である。l\leq m<r から、いずれも 0\leq L'<L を満たす。
したがって、非負整数である区間長は一致によって終了しない各反復で厳密に減少する。このため反復は有限回で終了する。
6計算量
一回の更新後の区間長 L' は
L'\leq\left\lfloor\frac{L}{2}\right\rfloor
を満たす。n=0 なら反復は行われない。n\geq1 では、k 回の更新後に区間長が高々 \lfloor n/2^k\rfloor となる。2^k>n を満たせば区間は空になるため、反復回数は高々 \lfloor\log_2 n\rfloor+1 回である。よって時間計算量は O(\log(n+1))、追加領域は O(1) である。
7算法の要約
- [l,r)=[0,n) とする。
- l<r の間、m=\lfloor(l+r)/2\rfloor を計算する。
- A_m=x なら m を返す。x<A_m なら r=m、A_m<x なら l=m+1 とする。
- l=r なら不在を返す。
二分探索の正当性は、昇順性による候補の除外、不変条件の保存、および区間長の厳密減少から導かれる。