СНМ с операцией удаления за О(1) — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Введение)
Строка 6: Строка 6:
  
 
* <tex>makeset(x)</tex> - создать новое множество из 1 элемента <tex>x </tex>. Время: <tex>O(1)</tex>
 
* <tex>makeset(x)</tex> - создать новое множество из 1 элемента <tex>x </tex>. Время: <tex>O(1)</tex>
* <tex>union(A, B)</tex> - объединить множества A и B в одно. Время: <tex> O(1) </tex>, без учета времени на операцию <tex>find()</tex>, которая используется, если множества A и B заданы своими произвольными представителями.
+
* <tex>union(A, B)</tex> - объединить множества A и B в одно. Время: <tex> O(1) </tex>, без учета времени на операцию <tex>find</tex>, которая используется, если множества A и B заданы своими произвольными представителями.
 
* <tex>find(x)</tex> - найти множество, в котором содержится элемент <tex> x </tex>. Время; <tex>O(log n)</tex> в худшем случае, <tex>O(\alpha(n))</tex> - в среднем (<tex>\alpha(n)</tex> - обратная функция Аккермана), где n - размер множества.
 
* <tex>find(x)</tex> - найти множество, в котором содержится элемент <tex> x </tex>. Время; <tex>O(log n)</tex> в худшем случае, <tex>O(\alpha(n))</tex> - в среднем (<tex>\alpha(n)</tex> - обратная функция Аккермана), где n - размер множества.
 
* <tex>delete(x)</tex> - удалить элемент x из содержащего его множества. Время: O(1)
 
* <tex>delete(x)</tex> - удалить элемент x из содержащего его множества. Время: O(1)
Строка 16: Строка 16:
 
* <tex>h(v)</tex> - высота вершины <tex>v</tex>: если <tex>v</tex> является листом, то <tex>h(v) = 0</tex>, иначе <tex>h(v) = max { h(w) | w - ребенок v } </tex>.
 
* <tex>h(v)</tex> - высота вершины <tex>v</tex>: если <tex>v</tex> является листом, то <tex>h(v) = 0</tex>, иначе <tex>h(v) = max { h(w) | w - ребенок v } </tex>.
 
* <tex>p(v)</tex> - родитель вершины <tex>v</tex>. Если <tex>v</tex> - корень, то считаем, что <tex>p(v) = v</tex>
 
* <tex>p(v)</tex> - родитель вершины <tex>v</tex>. Если <tex>v</tex> - корень, то считаем, что <tex>p(v) = v</tex>
* <tex>rank(v)</tex> - ранг вершины, некоторая верхняя оценка на ее высоту. Как и в [[СНМ_(реализация_с_помощью_леса_корневых_деревьев)|обычной реализации]], выполнено следующее: '''ранг родителя вершин 
+
* <tex>rank(v)</tex> - ранг вершины, некоторая верхняя оценка на ее высоту.
 +
 
 +
Как и в [[СНМ_(реализация_с_помощью_леса_корневых_деревьев)|обычной реализации]], выполнено следующее: <tex>rank(v) < rank(p(v))</tex>
  
 
== Реализация ==
 
== Реализация ==

Версия 20:21, 31 мая 2014

Реализация системы непересекающихся множеств с помощью леса корневых деревьев не поддерживает операцию удаления элемента из множества. Приведенная ниже модификация этой структуры данных вводит поддержку операции удаления за О(1) в худшем случае, сохраняя асимптотику для операций Union и Find и потребление памяти O(n).

Введение

Наша структура данных должна поддерживать следующие операции:

  • [math]makeset(x)[/math] - создать новое множество из 1 элемента [math]x [/math]. Время: [math]O(1)[/math]
  • [math]union(A, B)[/math] - объединить множества A и B в одно. Время: [math] O(1) [/math], без учета времени на операцию [math]find[/math], которая используется, если множества A и B заданы своими произвольными представителями.
  • [math]find(x)[/math] - найти множество, в котором содержится элемент [math] x [/math]. Время; [math]O(log n)[/math] в худшем случае, [math]O(\alpha(n))[/math] - в среднем ([math]\alpha(n)[/math] - обратная функция Аккермана), где n - размер множества.
  • [math]delete(x)[/math] - удалить элемент x из содержащего его множества. Время: O(1)

В дальнейшем мы будем использовать следующие понятия и обозначения:

  • [math]size(A)[/math] - размер множества A (количество элементов в нем).
  • [math]root(T_A)[/math] - корень дерева [math]T_A[/math]
  • [math]h(v)[/math] - высота вершины [math]v[/math]: если [math]v[/math] является листом, то [math]h(v) = 0[/math], иначе [math]h(v) = max { h(w) | w - ребенок v } [/math].
  • [math]p(v)[/math] - родитель вершины [math]v[/math]. Если [math]v[/math] - корень, то считаем, что [math]p(v) = v[/math]
  • [math]rank(v)[/math] - ранг вершины, некоторая верхняя оценка на ее высоту.

Как и в обычной реализации, выполнено следующее: [math]rank(v) \lt rank(p(v))[/math]

Реализация

Расширение структуры данных

Расширим лес корневых деревьев следующим образом:

  • Для каждой вершины дерева, не являющейся листом, будем хранить двусвязный список [math] \mathrm{C_{list}} [/math] ее детей. Будем считать, что дети упорядочены по направлению списка слева направо.
  • Для корня каждого дерева храним двусвязный список [math] \mathrm{NL_{list}} [/math] его детей, не являющихся листьями.
  • Для каждого дерева (включая поддеревья) храним циклический двусвязный список [math] \mathrm{DFS_{list}} [/math] его вершин, располагаемых в порядке обхода в глубину, начиная с левой вершины.
  • Разделим понятия вершина дерева и элемент множества:
    • вершиной дерева назовем объект, содержащий ссылки [math]next[/math], [math]prev[/math] и [math]head[/math] (где необходимо) для каждого из вышеперечисленных списков, а так же ссылку на соответствующий вершине элемент множества;
    • элемент множества - объект, содержащий значение элемента и ссылку на соотв. вершину дерева.

Введем также следующие определения:


Определение:
Дерево, либо состоящее ровно из одной вершины, либо же из 1 вершины ранга 1 и листьев ранга 0, называется сокращенным (reduced)


Определение:
Дерево называется полным, если каждый из его узлов либо является листом с рангом 0, либо имеет не менее 3 детей.


В нашей структуре данных будет поддерживаться следующий инвариант: дерево является либо только полным, либо только сокращенным. Этот инвариант влечет за собой очевидные следствия:

  • Все деревья (и поддеревья) размера < 4 - сокращенные, а >= 4 - полные
  • Каждая вершина, среди детей которой есть хотя бы 1 нелистовая вершина, имеет не менее 3 детей (это не позволяет дереву вытягиваться в бамбук, например)