Несвязанная структура данных набора
Это код для Findind непересекающихся множеств
class disjoint_sets {
struct disjoint_set {
size_t parent;
unsigned rank;
disjoint_set(size_t i) : parent(i), rank(0) { }
};
std::vector<disjoint_set> forest;
public:
disjoint_sets(size_t n){
forest.reserve(n);
for (size_t i=0; i<n; i++)
forest.push_back(disjoint_set(i));
}
size_t find(size_t i){
if (forest[i].parent == i)
return i;
else {
forest[i].parent = find(forest[i].parent);
return forest[i].parent;
}
}
void merge(size_t i, size_t j) {
size_t root_i = find(i);
size_t root_j = find(j);
if (root_i != root_j) {
if (forest[root_i].rank < forest[root_j].rank)
forest[root_i].parent = root_j;
else if (forest[root_i].rank > forest[root_j].rank)
forest[root_j].parent = root_i;
else {
forest[root_i].parent = root_j;
forest[root_j].rank += 1;
}
}
}
};
Почему мы увеличиваем ранг, если ранги равны? Извините новичка, а также что делает шаг поиска??
1 ответ
Потому что в этом случае - вы добавляете одно дерево как "поддерево" другого - что заставляет исходное поддерево увеличивать его размер.
Посмотрите на следующий пример:
1 3
| |
2 4
В приведенном выше "ранг" каждого дерева равен 2.
Теперь предположим, что 1 будет новым унифицированным корнем, вы получите следующее дерево:
1
/ \
/ \
3 2
|
4
после объединения ранг "1" равен 3, rank_old(1) + 1
- как и ожидалось.