kaisehのブログ このページをアンテナに追加

2007-12-31

要素の挿入、削除、ランダムアクセスが全部高速なリストを作った

スキップリスト(Skip List)は1990年に発表された比較的新しいアルゴリズムで、要素の挿入や削除、検索を平衡木と同等のパフォーマンスで実行可能なリスト構造です。

Skip Listは連結リストの多層構成になっています。路線に例えると、最下層のリンクは各駅停車のように、全要素を結んでいます。一方、上層のリンクは急行や特急のように、途中の要素をスキップするようになっています。この路線を特急→急行→…→各駅と乗り継ぐことで、目的の要素に高速に到達できる仕組みです。もっと詳しい解説はこちらこちらにあります。

f:id:kaiseh:20080101003042p:image

で、ここからが本題です。Skip Listの実装はいくつも出ているんですが、Sorted Listとしての実装ばかりで、要素を任意順序で格納できてランダムアクセス(indexを指定してのアクセス)可能なSkip Listが見つからなかったので、自分で作ってみました。

通常のSkip Listでは、各ノードは次のノードへのリンクしか保持していません。ここに少し工夫を加えて、上の画像のように、次ノードまでの「距離」を持たせるようにしました。ノード探索時にこの距離を加算していくことで、indexによる要素の取得をO(logN)で実行できます。

このSkipListに加えて、java.util.Listとjava.util.Setを両方実装したSkipListSetというものも作りました。こちらは内部的にHashMapを併用していて、indexOf()やcontains()も高速になっています。各メソッドの計算量比較は以下の通りです。

メソッドArrayListSkipListSkipListSet
get(index)O(1)O(logN)O(logN)
set(index, element)O(1)O(logN)O(logN)
add(element)O(1)O(logN)O(logN)
add(index, element)O(N)O(logN)O(logN)
remove(index)O(N)O(logN)O(logN)
remove(element)O(N)O(N)O(logN)
indexOf(element)O(N)O(N)O(logN)
contains(element)O(N)O(N)O(1)
iterator().next()O(1)O(1)O(1)

ソースは以下からどうぞ。

ryopeiryopei 2010/11/11 12:27 以前、twitterでSwingのバインディングについて質問をさせていただいたものです。突然の質問にもお答えいただきありがとうございました。
明日google appengineの勉強回があるのですが、Listの計算量比較表を引用させていただきたいのですが、よろしいでしょうか?

kaisehkaiseh 2010/11/11 12:35 全く問題ありません!よろしくお願いします。

ryopeiryopei 2010/11/11 12:55 ありがとうございます。活用させていただきます!

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証