Сегодня я обсуждал с кем-то алгоритм минимального связующего дерева Крускала из-за страницы 13 из этого слайда .
Автор презентации сказал, что если мы реализуем непересекающиеся множества, используя (дважды) связанный список, производительность для Make и Find будет O (1) и O (1) соответственно. Время операции Union (u, v) равно min (nu, nv) , где nu и nv - размеры наборы, хранящие вас и 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 в различных реализациях? Я не эксперт в области структуры данных, но благодаря быстрому просмотру в Интернете я обнаружил, что для этого не существует структуры данных или алгоритма с постоянным временем.