Система непересекающихся множеств (англ.disjoint-set, или union–finddata structure) — структура данных, которая позволяет администрировать множество элементов, разбитое на непересекающиеся подмножества. При этом каждому подмножеству назначается его представитель — элемент этого подмножества. Абстрактная структура данных определяется множеством трёх операций: .
Пусть конечное множество, разбитое на непересекающиеся подмножества (классы) :
.
Каждому подмножеству назначается представитель .
Соответствующая система непересекающихся множеств поддерживает следующие операции:
: создаёт для элемента новое подмножество. Назначает этот же элемент представителем созданного подмножества.
: объединяет оба подмножества, принадлежащие представителям и , и назначает представителем нового подмножества.
: определяет для подмножество, к которому принадлежит элемент, и возвращает его представителя.
Алгоритмическая реализация
Тривиальная реализация сохраняет принадлежность элементов из и представителей в индексном массиве. На практике же чаще используются множества деревьев. Это позволяет существенно сократить время, необходимое для операции Find. При этом представитель записывается в корень дерева, а остальные элементы класса в узлы под ним.
: вешает корень более низкого дерева под корень более высокого дерева. Если при этом становится потомком , оба узла меняются местами.
: проходит путь от до корня дерева и возвращает его (корень в данном случае является представителем).
Эвристики
Для ускорения операций Union и Find могут быть использованы эвристики Union-By-Size, Union-By-Height, Random-Union и сжатие путей.
В эвристике Union-By-Size во время операции корень меньшего дерева вешается под корень большего дерева. Благодаря этому подходу сохраняется балансировка дерева. Глубина каждого поддерева не может превысить величину . При использовании этой эвристики время операции Find в худшем случае увеличивается с до . Для эффективной реализации предлагается сохранять в корне количество узлов в дереве.
Эвристика Union-By-Height аналогична Union-By-Size, но использует высоту дерева вместо размера.
В эвристике Random-Union используется тот факт, что можно не тратить дополнительные памяти на сохранение количества узлов в дереве: достаточно выбирать корень случайным образом — такое решение даёт на случайных запросах скорость, вполне сравнимую с другими реализациями. Тем не менее, если имеется много запросов вида «объединить большое множество с маленьким», данная эвристика улучшает матожидание (то есть среднее время работы) всего в два раза, поэтому использовать её без эвристики сжатия путей не рекомендуется.
Эвристика сжатия путей используется, чтобы ускорить операцию . При каждом новом поиске все элементы, находящиеся на пути от корня до искомого элемента, вешаются под корень дерева. В этом случае операция Find будет работать в среднем , где — функция, обратная функции Аккермана. Это позволяет значительно ускорить работу, так как для всех применяемых на практике значений принимает значение, меньшее 5.