Blender V4.3
BLI_disjoint_set.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
13#include "BLI_array.hh"
14#include "BLI_index_range.hh"
15
16namespace blender {
17
18template<typename T = int64_t> class DisjointSet {
19 private:
20 Array<T> parents_;
21 Array<T> ranks_;
22
23 public:
27 DisjointSet(const int64_t size) : parents_(size), ranks_(size, 0)
28 {
29 BLI_assert(size >= 0);
30 for (const int64_t i : IndexRange(size)) {
31 parents_[i] = T(i);
32 }
33 }
34
39 void join(const T x, const T y)
40 {
41 T root1 = this->find_root(x);
42 T root2 = this->find_root(y);
43
44 /* x and y are in the same set already. */
45 if (root1 == root2) {
46 return;
47 }
48
49 /* Implement union by rank heuristic. */
50 if (ranks_[root1] < ranks_[root2]) {
51 std::swap(root1, root2);
52 }
53 parents_[root2] = root1;
54
55 if (ranks_[root1] == ranks_[root2]) {
56 ranks_[root1]++;
57 }
58 }
59
63 bool in_same_set(const T x, const T y)
64 {
65 T root1 = this->find_root(x);
66 T root2 = this->find_root(y);
67 return root1 == root2;
68 }
69
73 T find_root(const T x)
74 {
75 /* Find root by following parents. */
76 T root = x;
77 while (parents_[root] != root) {
78 root = parents_[root];
79 }
80
81 /* Compress path. */
82 T to_root = x;
83 while (parents_[to_root] != root) {
84 const T parent = parents_[to_root];
85 parents_[to_root] = root;
86 to_root = parent;
87 }
88
89 return root;
90 }
91};
92
93} // namespace blender
#define BLI_assert(a)
Definition BLI_assert.h:50
DisjointSet(const int64_t size)
void join(const T x, const T y)
bool in_same_set(const T x, const T y)
#define T
__int64 int64_t
Definition stdint.h:89