1 整列の問題と、示すべき三つのこと
定義 1.1 (整列の問題). 全順序が与えられた集合の相異なる要素からなる列a1,a2,…,anを入力とする。[n]の置換πでaπ(1)<aπ(2)<⋯<aπ(n)を満たすものを求める問題を整列という。入力の要素が相異なるとき、このπはただ一つに定まる。手続きの出力は、この順に並べ替えた列aπ(1),…,aπ(n)とする。
整列の手続きについて示すことは、次の三つです。第一は、停止したときの出力が入力の要素を並べ替えた列であり、かつ昇順に並んでいることです。第二は、どの入力に対しても有限回の操作で停止することです。第三は、操作の回数の評価です。本記事では、操作の回数を要素どうしの比較の回数で測ります。
2 併合による整列
併合による整列は、列を二つに分け、それぞれを整列してから、二つの整列済みの列を一つに併せます。最後の操作を先に定めます。
定義 2.1 (併合). 昇順に並んだ二つの列x1<x2<⋯<xpとy1<y2<⋯<yqを入力とし、次の手順を併合という。
- i←1、j←1とし、出力列zを空の列とする。
- i≤pかつj≤qである間、次を繰り返す。xiとyjを比較する。xi<yjならばxiをzの末尾へ加えてi←i+1とし、そうでなければyjをzの末尾へ加えてj←j+1とする。
- 繰り返しを抜けたのち、xi,…,xpとyj,…,yqのうち残っているほうを、そのままの順でzの末尾へ加え、zを出力する。
正しい答えを返すことは、繰り返しのたびに保たれる条件によって示します。
補題 2.2.定義 2.1の手順は、x1,…,xpとy1,…,yqのすべての要素をちょうど一度ずつ含む昇順の列を出力する。
証明.
主張 2.2.1. 手順 2 の各回を始める時点で、次の三つが成り立ちます。
- 出力列zは昇順に並んでいます。
- zの要素の全体は{x1,…,xi−1}∪{y1,…,yj−1}に一致し、どの要素もちょうど一度ずつ現れます。
- zのどの要素も、xi,…,xpとyj,…,yqのどの要素より小さいです。
証明. 繰り返しに入る前はi=j=1でzは空なので、三つの主張はすべて空虚に成り立ちます。
一回の繰り返しを始める時点で三つの主張が成り立っているとし、xi<yjの場合を考えます(そうでない場合も、xとyの役割を入れ替えれば同じです)。手順はxiをzの末尾へ加えます。主張 2.2.1 (3)によりzのどの要素もxiより小さいので、xiを末尾に加えた列は昇順のままであり、主張 2.2.1 (1)が保たれます。iが1増えるので、要素の全体についての主張 2.2.1 (2)も保たれます。主張 2.2.1 (3)については、加えたxiがxi+1,…,xpより小さいこと(入力が昇順であること)と、xi<yj<yj+1<⋯<yqであることから、xiは残っているどの要素より小さく、zの他の要素についてはもとの主張 2.2.1 (3)がそのまま使えます。よって三つとも保たれます。▨
繰り返しを抜けた時点ではi>pまたはj>qです。i>pの場合、残っているのはyj,…,yqだけであり、主張 2.2.1 (3)によりこれらはzのどの要素よりも大きく、しかも昇順に並んでいます。したがって手順 3 でこれらを末尾へ加えた列は昇順であり、主張 2.2.1 (2)とあわせて、入力の全要素をちょうど一度ずつ含みます。j>qの場合も同様です。▨
補題 2.3.定義 2.1の手順は必ず停止し、行う比較の回数はp+q−1以下である。
証明. 量μ=(p−i+1)+(q−j+1)を考えます。手順 2 の各回でiまたはjのちょうど一方が1増えるので、μはちょうど1減ります。また繰り返しの条件i≤pかつj≤qのもとでμ≥2>0です。μは非負の整数で毎回真に減るので、繰り返しは有限回で終わり、手順 3 は繰り返しを含まないので、手続き全体が停止します。
比較は手順 2 の各回でちょうど一回行われるので、比較の回数は繰り返しの回数に等しく、繰り返しの回数はzへ加えられた要素の個数に等しくなります。繰り返しを抜けた時点でi>pまたはj>qですが、繰り返しの条件から、抜ける直前の回ではi≤pかつj≤qであり、増えるのは一方だけです。したがって抜けた時点でもう一方の列には少なくとも一つの要素が残っており、その要素は手順 3 で加えられます。すなわち手順 2 でzへ加えられた要素はp+q−1個以下であり、比較の回数もp+q−1以下です。▨
併合を使って、整列の手続きを再帰的に定めます。
定義 2.4 (併合による整列). 列Lを入力とする次の手続きを併合による整列という。Lの長さをnとする。
- n≤1ならばLをそのまま出力する。
- n≥2ならば、Lを先頭から⌈n/2⌉個の列L1と、残りの⌊n/2⌋個の列L2に分ける。L1とL2のそれぞれへこの手続きを適用して整列した列を得る。
- 得られた二つの整列済みの列を併合し、その結果を出力する。
定理 2.5.定義 2.4の手続きは、どの入力に対しても停止し、入力の要素を昇順に並べ替えた列を出力する。
証明. 入力の長さnについての累積帰納法(§D2.1 命題 1.2)で示します。
n≤1のとき、長さ0または1の列は昇順に並んでいるので、手順 1 の出力は正しく、繰り返しも再帰も行わないので停止します。
n≥2とし、長さがnより小さいどの入力についても主張が成り立つと仮定します。⌈n/2⌉と⌊n/2⌋はどちらも1以上n−1以下なので、L1とL2への再帰は帰納法の仮定の範囲にあり、いずれも停止して、L1とL2の要素を昇順に並べた列を返します。補題 2.3により併合も停止するので、手続き全体が停止します。補題 2.2により、出力は二つの列の要素をちょうど一度ずつ含む昇順の列です。L1とL2の要素をあわせたものはLの要素にほかならないので、出力はLの要素を昇順に並べ替えた列です。▨
停止することの根拠は、再帰の呼び出しごとに入力の長さが真に小さくなることです。長さは非負整数なので、真に小さくなり続けることはできません。これは、長さの比較が整礎な関係であることを用いた議論であり、§D2.1 定理 2.3の形をしています。
比較の回数は、分割から生じる漸化式によって評価します。
命題 2.6. 長さn≥1の入力に対して定義 2.4が行う比較の回数の最大値をC(n)とすると
C(n)≤n⌈log2n⌉が成り立つ。
証明.定義 2.4の構造と補題 2.3から、C(1)=0であり、n≥2について
C(n)≤C(⌈n/2⌉)+C(⌊n/2⌋)+n−1が成り立ちます。この不等式のもとで主張をnについての累積帰納法で示します。
n=1のときはC(1)=0=1⋅⌈log21⌉です。
n≥2とし、nより小さいすべての正の整数について主張が成り立つと仮定します。k=⌈log2n⌉とおくと、n≥2よりk≥1であり、n≤2kです。よって⌈n/2⌉≤2k−1であり、⌊n/2⌋≤⌈n/2⌉≤2k−1なので、どちらについても⌈log2(⋅)⌉≤k−1です。また⌈n/2⌉と⌊n/2⌋はどちらも1以上n−1以下なので、帰納法の仮定を適用することができ、
C(n)≤⌈n/2⌉(k−1)+⌊n/2⌋(k−1)+n−1=n(k−1)+n−1=nk−1<n⌈log2n⌉が得られます。▨
比較以外の操作も含めた手数は、分割統治の漸化式から求めることができます。長さnの列を二つに分ける操作と併合の操作はいずれもΘ(n)の手数で行うことができるので、全体の手数T(n)はT(n)=2T(n/2)+Θ(n)を満たします。マスター定理(§D2.8 定理 3.1)の場合 2 によりT(n)=Θ(nlogn)です。
3 分割による整列
分割による整列は、順序を先に決めてから並べます。すなわち、要素を一つ選んでそれより小さい要素と大きい要素に分け、それぞれを整列してから、間に選んだ要素を挟んで並べます。併合による整列とは、手間をかける場所が逆になっています。
定義 3.1 (分割による整列). 列Lを入力とする次の手続きを分割による整列という。Lの長さをnとする。
- n≤1ならばLをそのまま出力する。
- n≥2ならば、Lの先頭の要素aを軸とする。残りのn−1個の要素をそれぞれaと一度ずつ比較し、aより小さい要素を集めた列L<と、aより大きい要素を集めた列L>に分ける。
- L<とL>のそれぞれへこの手続きを適用して整列し、得られた二つの列のあいだにaを置いて並べた列を出力する。
定理 3.2.定義 3.1の手続きは、どの入力に対しても停止し、入力の要素を昇順に並べ替えた列を出力する。
証明. 入力の長さnについての累積帰納法で示します。n≤1のときは定理 2.5の証明と同じです。
n≥2とし、長さがnより小さいどの入力についても主張が成り立つと仮定します。入力の要素は相異なるので、a以外のn−1個の要素はそれぞれL<とL>のちょうど一方に入り、∣L<∣+∣L>∣=n−1です。したがって∣L<∣と∣L>∣はどちらもn−1以下、すなわちnより小さいので、帰納法の仮定を適用することができ、二つの再帰はいずれも停止して、それぞれの要素を昇順に並べた列を返します。手順 3 は繰り返しを含まないので、手続き全体が停止します。
出力が昇順であることを確かめます。L<を整列した列のどの要素もaより小さく、L>を整列した列のどの要素もaより大きいので、三つをこの順に並べた列は昇順です。また出力はL<の要素、a、L>の要素をちょうど一度ずつ含み、これはLの要素の全体にほかなりません。▨
比較の回数は、軸によってどのように分かれるかで大きく変わります。
命題 3.3. 長さn≥1の入力に対して定義 3.1が行う比較の回数について、次が成り立つ。
- 比較の回数は、どの入力に対しても2n(n−1)以下である。
- すでに昇順に並んでいる入力に対する比較の回数は、ちょうど2n(n−1)である。
- どの再帰の段階でもL<とL>の長さの差が1以下であるとき、手数T(n)はT(n)=2T(n/2)+Θ(n)を満たし、T(n)=Θ(nlogn)である。
証明. 1 を示します。 比較の回数の最大値をW(n)とすると、W(1)=W(0)=0であり、n≥2について、手順 2 がn−1回の比較を行い、∣L<∣+∣L>∣=n−1であることから
W(n)≤0≤s≤n−1max(W(s)+W(n−1−s))+n−1が成り立ちます。W(n)≤n(n−1)/2をnについての累積帰納法で示します。n≤1では両辺が0です。n≥2とし、nより小さいすべての場合に主張が成り立つとすると、0≤s≤n−1に対して
W(s)+W(n−1−s)≤2s(s−1)+2(n−1−s)(n−2−s)です。右辺を展開して整理すると、sの関数として
2s(s−1)+2(n−1−s)(n−2−s)=s2−(n−1)s+2(n−1)(n−2)となります。s2−(n−1)s=s(s−(n−1))は0≤s≤n−1の範囲で0以下であり、端点s=0とs=n−1で最大値0をとります。したがって右辺の最大値は(n−1)(n−2)/2です。よって
W(n)≤2(n−1)(n−2)+(n−1)=2(n−1)nとなります。
2 を示します。 入力がすでに昇順であるとき、先頭の要素は最小なのでL<は空、L>は残りのn−1個からなり、しかも昇順のままです。したがって比較の回数をR(n)とするとR(1)=0かつR(n)=R(n−1)+(n−1)です。R(n)=n(n−1)/2がnについての単純帰納法で従います。実際、R(1)=0=1⋅0/2であり、R(n)=(n−1)(n−2)/2+(n−1)=n(n−1)/2です。
3 を示します。 分割の操作はn−1回の比較と、それに伴うΘ(n)の手数で行うことができ、仮定から二つの部分列の長さはどちらもn/2と定数の差しかありません。よってT(n)=2T(n/2)+Θ(n)が成り立ち、マスター定理(§D2.8 定理 3.1)の場合 2 によりT(n)=Θ(nlogn)です。▨
4 比較に基づく整列の下界
ここからは、一つの手続きではなく、手続きの集まり全体についての主張を扱います。そのためには、どの範囲の手続きを考えるのかを先に定めなければなりません。
定義 4.1 (比較に基づく整列). 整列の手続きが比較に基づくとは、入力の要素に対して行う操作が、二つの要素を取り出してどちらが小さいかを問う比較だけであり、次にどの比較を行うか、いつ停止するか、および停止したときにどの並べ替えを出力するかが、それまでに行った比較の結果の列だけによって定まることをいう。
この定義では、要素の値そのものを位置や添字の計算に用いる手続きを除いている。以下では、要素の個数nを固定し、手続きは相異なるn個の要素からなるどの入力に対しても有限回の比較で停止するものとする。
比較に基づく手続きでは、入力の要素の大小関係が同じであれば、行われる比較の結果も同じになります。相異なるn個の要素の大小関係は、[n]の置換πによってaπ(1)<⋯<aπ(n)という形で表されるので、比較の結果の列はπだけで定まります。
定義 4.2 (決定木). 比較に基づく整列の手続きAと要素の個数nを固定する。[n]の置換πに対し、Aがπで表される大小関係をもつ入力に対して行う比較の結果を、行った順に並べた0と1の列をr(π)と書く。r(π)の接頭辞の全体を、πが[n]の置換すべてを動くときに集めた集合をTとする。Tの要素を節点、空列を根とし、列sの子をs0とs1のうちTに属するものと定めると、Tは根つき二分木になる。この木をAの決定木という。子をもたない節点を葉、根から節点へ至る辺の本数をその節点の深さ、深さの最大値を木の高さという。
決定木の高さは、Aが相異なるn個の要素からなる入力に対して行う比較の回数の最大値に等しくなります。したがって、比較の回数の下界は、決定木の高さの下界として得られます。証明は二段に分かれます。葉の個数が下から抑えられることと、高さが低い二分木には葉が少ないことです。
補題 4.3.定義 4.2の決定木は、少なくともn!個の葉をもつ。
証明. まず、相異なる置換π=π′に対してr(π)=r(π′)であることを示します。r(π)=r(π′)と仮定すると、Aの動作は比較の結果の列だけで定まるので、Aは二つの入力に対して同じ並べ替えを出力します。しかしAは正しい整列の手続きなので、大小関係がπで表される入力に対する正しい出力はπによる並べ替えに限られ(定義 1.1)、π′についても同様です。π=π′なので二つの出力は異なり、矛盾します。
次に、各r(π)が決定木の葉であることを示します。r(π)が子をもつとすると、r(π)0またはr(π)1がTに属し、それはあるπ′についてr(π′)の接頭辞です。すなわちr(π)はr(π′)の真の接頭辞です。ところが定義 4.1により、手続きが停止するかどうかはそれまでの比較の結果の列だけで定まります。πに対しては比較の結果の列がr(π)になった時点で停止するので、π′に対しても、比較の結果の列がr(π)に一致した時点で停止し、r(π′)=r(π)となります。これはr(π)がr(π′)の真の接頭辞であることに反します。よってr(π)は葉です。
以上より、[n]のn!個の置換に対するr(π)は互いに相異なる葉を与えるので、葉の個数はn!以上です。▨
補題 4.4. 高さがhである根つき二分木の葉の個数は2h以下である。
証明.hについての単純帰納法(§A3.10 定理 1.1)で示します。
h=0のとき、木は根だけからなり、根は子をもたないので葉です。葉の個数は1=20です。
h≥1とし、高さがh−1以下の二分木について主張が成り立つと仮定します。高さhの二分木Tをとります。h≥1なので根は少なくとも一つの子をもち、根自身は葉ではありません。根の子は高々二つで、各子を根とする部分木の高さはh−1以下です。Tの葉は、これらの部分木の葉をすべて集めたものに一致します。帰納法の仮定により各部分木の葉は2h−1個以下なので、Tの葉は2⋅2h−1=2h個以下です。▨
定理 4.5. 比較に基づく整列の手続きが、相異なるn個の要素からなる入力に対して行う比較の回数の最大値をhとすると
h≥⌈log2(n!)⌉が成り立つ。
証明. 決定木の高さはhです。補題 4.3により葉の個数はn!以上であり、補題 4.4により葉の個数は2h以下です。よってn!≤2h、すなわちlog2(n!)≤hです。hは整数なので、log2(n!)以上の整数のうち最小のもの、すなわち⌈log2(n!)⌉以上です。▨
系 4.6. 比較に基づく整列の手続きが行う比較の回数の最大値hは、n≥1についてh≥2nlog2nを満たす。とくにh=Ω(nlogn)である。
証明.n!≥nn/2を示します。積(n!)2=∏k=1nk⋅∏k=1n(n+1−k)を、同じkの項どうしでまとめると(n!)2=∏k=1nk(n+1−k)です。1≤k≤nにおいて
k(n+1−k)−n=−(k−1)(k−n)=(k−1)(n−k)≥0なのでk(n+1−k)≥nです。よって(n!)2≥nn、すなわちn!≥nn/2です。両辺のlog2をとるとlog2(n!)≥2nlog2nであり、定理 4.5とあわせてh≥2nlog2nが得られます。▨
例 4.7.n=3のとき3!=6で22=4<6≤8=23なので、下界は⌈log26⌉=3である。実際に3回で足りる。a1とa2を比較して小さいほうをu、大きいほうをvとし、a3をvと比較する。a3>vならばu<v<a3で終わり、そうでなければa3をuと比較して、a3がuより小さいか、uとvのあいだにあるかを決める。最悪でも3回である。
n=4のとき4!=24で24=16<24≤32=25なので、下界は5である。併合による整列は、長さ2の列二つへ分けて各々に1回、併合に補題 2.3より3回以下なので、合計5回以下で整列する。下界と一致するので、n=4では併合による整列は比較の回数の意味で最良である。
一方命題 2.6により与えられる上界は4⌈log24⌉=8であり、実際の5より大きい。上界は、正しいことが保証された評価であって、最良の評価とは限らない。