今日、このスライドの 13 ページのために、Kruskal 最小スパニング ツリー アルゴリズムについて誰かと議論しました。
プレゼンテーションの著者は、(二重) リンク リストを使用して素集合を実装すると、MakeとFindのパフォーマンスはそれぞれ O (1)とO(1 )になると述べています。Union(u,v)操作の時間はmin(nu,nv)です。ここで、nuとnvは u と v を格納するセットのサイズです。
セットの実表現へのポインターを含むロケーターを指す各メンバーの表現ポインターを作成することにより、 Union(u,v)がO(1)になる時間を改善できると述べました。
Java では、データ構造は次のようになります。
class DisjointSet {
LinkedList<Vertex> list = new LinkedList<Vertex>(); // for holding the members, we might need it for print
static Member makeSet(Vertex v) {
Member m = new Member();
DisjointSet set = new DisjointSet();
m.set = set;
set.list.add(m);
m.vertex = v;
Locator loc = new Locator();
loc.representation = m;
m.locator = loc;
return m;
}
}
class Member {
DisjointSet set;
Locator locator;
Vertex vertex;
Member find() {
return locator.representation;
}
void union(Member u, Member v) { // assume nv is less than nu
u.set.list.append(v.set.list); // hypothetical method, append a list in O(1)
v.set = u.set;
v.locator.representation = u.locator.representation;
}
}
class Locator {
Member representation;
}
ミニマルなコードで申し訳ありません。この方法で作成できる場合、互いに素な集合操作 ( Make,Find,Union )ごとの実行時間はO(1)になります。しかし、私が話し合った人は改善を見ることができません。これについてあなたの意見を知りたいです。
また、さまざまな実装における Find/Union の最速のパフォーマンスは? 私はデータ構造の専門家ではありませんが、インターネットをざっと見てみると、これを行う一定時間のデータ構造やアルゴリズムがないことがわかりました。