サイズnおよびmのタイプTの 2つのソートされた配列a、bが与えられます。2つの配列を(最大サイズn + mの)新しい配列にマージするアルゴリズムを探しています。
安価な比較操作がある場合、これは非常に簡単です。1つまたは両方の配列が完全に走査されるまで、最初の要素が最も低い配列から取り出し、残りの要素を追加します。このようなもの/programming/5958169/how-to-merge-two-sorted-arrays-into-a-sorted-array
ただし、2つの要素を比較すると、ソース配列からターゲット配列に要素をコピーするよりもはるかに高価な場合、状況は変わります。たとえば、大きな任意精度の整数または文字列の配列があり、比較が非常に高価になる場合があります。配列の作成と要素のコピーは無料で、コストがかかるのは要素を比較することだけだと考えてください。
この場合、要素比較の最小数で 2つの配列をマージします。以下に、単純なマージアルゴリズムよりもはるかに優れた機能を発揮できるいくつかの例を示します。
a = [1,2,3,4, ... 1000]
b = [1001,1002,1003,1004, ... 2000]
または
a = [1,2,3,4, ... 1000]
b = [0,100,200, ... 1000]
次のように、単純なマージアルゴリズムが最適になる場合があります。
a = [1,3,5,7,9,....,999]
b = [2,4,6,8,10,....,1000]
したがって、アルゴリズムは、配列がインターリーブされている場合、または少なくとも大幅に悪化していない場合に、理想的には正常に低下し、最大n + m-1回の比較を実行する必要があります。
サイズの違いが大きいリストに対しては、バイナリ検索を使用して、小さな配列の要素を大きな配列に挿入することで、かなりうまくいくはずです。しかし、両方のリストが同じサイズでインターリーブされている場合、それは適切に低下しません。
要素で利用できるのは(合計)順序関数のみであるため、比較を安価にするスキームは不可能です。
何か案は?
私はScalaでこのビットを思いつきました。比較の数に関しては最適であると思いますが、それを証明する能力を超えています。少なくとも、私が文献で見つけたものよりもずっと簡単です。
そして、最初の投稿以来、これがどのように機能するかについてのブログ投稿を書きました。