物事はシンプルであればあるほど記憶しやすく、組み合わせて何事かを処理するのも容易になります。アルゴリズムもシンプルであればあるほど優れていると言えます。ただ、物事をシンプルにする、とひとことで言っても、いくつかの処理のステップをまとめて1つの名前を付けること、つまり、抽象化によってシンプルにした場合には注意が必要です。抽象化してシンプルになった名前の裏では、汗水たらしててんてこ舞いして働いている人がいるかもしれませんから。営業担当者が「簡単です!うちに任してください!」といって取ってきた仕事を、製造現場の労働者が泣きの涙で作って出荷している・・・という笑えない状況と、どこか似ているような似ていないような。いえ、決して営業さんは悪くないんですよ。悪くないんですけど。
計算量:ハッシュサーチの場合O(1)
バイナリサーチは十分高速な検索アルゴリズムです。これ以上早いアルゴリズムがあるのでしょうか。結論から書くと、バイナリサーチが最速かつ適切でしょう。ただし、あらゆる場合に適切かというと、そうでもありません。
一般に検索のキーは整数ではなく文字列です。例えば住所録、商品データベースなどです。ある商品の検索を行う場合に、商品名が分かっても、商品番号が分からないのが普通です。名前を覚えずに番号で覚える奇特な人はそういません。そうした場合には、次のハッシュサーチが有望です。
ハッシュサーチ[1]とは、ものすごく強引に例えれば、教室の中で先生が生徒の名前を呼んで出席を取るような検索の方法です。名前を呼んだ生徒が出席していれば本人が返事をします。欠席ならば返事がありません。更に生徒の席が決まっていますから、そこに生徒がいるか見れば検索は一発で終了します。
ハッシュサーチの計算量はO(1)です。
もう少し具体的に解説しましょう。
ハッシュとは、ある大きさを持ったデータA(生徒)を、コンパクトな数値B(席)に対応させる操作のことです。このようなハッシュの仕組みを用いて、「検索を高速に行う」「データが改変されていないかを確認する」といった用途に用いられています。素早く出欠を確認し、代返が出来ないようにする仕組み、と言ったところでしょうか。
ハッシュを行う関数をハッシュ関数といいます。Java言語では、このハッシュを利用したデータ構造(Hashtable
クラス)を用意しています。プログラマはハッシュ関数のコードを書かなくとも、便利なデータ構造を利用することが出来ます。
ハッシュ関数のコード例
WikiPediaには次のようなハッシュ関数のコードが掲載されています。この関数の計算量はどれだけでしょうか?考えてみてください。答えは脚注に示しますので、一度考えてみてからご覧下さい[2]。