40#define OGDF_DISJOINT_SETS_INTERMEDIATE_PARENT_CHECK
70namespace disjoint_sets {
74template<LinkOptions linkOption>
77template<CompressionOptions compressionOption>
80template<InterleavingOptions
interleavingOption>
91 "Rem's Algorithm requires linking by index.");
93 "Tarjan and van Leeuwen's Algorithm requires linking by rank.");
96 "Interleaved Reversal Type 0 requires naïve linking.");
99 "Interleaved Path Splitting Path Compression requires linking by index.");
171 this->m_numberOfSets = 0;
172 this->m_numberOfElements = 0;
175 ?
new int[this->m_maxNumberOfElements]
178 ?
new int[this->m_maxNumberOfElements]
214 if (this->m_numberOfElements == this->m_maxNumberOfElements) {
216 this->m_parents =
new int[this->m_maxNumberOfElements * 2];
217 memcpy(this->m_parents,
parents,
sizeof(
int) * this->m_maxNumberOfElements);
220 if (this->m_parameters !=
nullptr) {
222 this->m_parameters =
new int[this->m_maxNumberOfElements * 2];
223 memcpy(this->m_parameters,
parameters,
sizeof(
int) * this->m_maxNumberOfElements);
227 if (this->m_siblings !=
nullptr) {
229 this->m_siblings =
new int[this->m_maxNumberOfElements * 2];
230 memcpy(this->m_siblings,
siblings,
sizeof(
int) * this->m_maxNumberOfElements);
233 this->m_maxNumberOfElements *= 2;
235 this->m_numberOfSets++;
236 int id = this->m_numberOfElements++;
237 this->m_parents[id] = id;
240 this->m_parameters[id] = 1;
242 this->m_parameters[id] = 0;
245 this->m_siblings[id] = -1;
261 this->m_numberOfSets--;
297 while (this->m_siblings[
id] != -1) {
298 id = this->m_siblings[id];
301 this->m_siblings[id] = this->m_siblings[
superset];
309template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
312 int parent = m_parents[set];
318 m_parents[set] = parent;
323template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
326 while (set != m_parents[set]) {
327 int parent = m_parents[set];
335template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
338 int parent = m_parents[set];
349template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
353 set = m_parents[root];
355 while (set != m_parents[set]) {
356 int parent = m_parents[set];
357 m_parents[set] = root;
360 m_parents[root] = set;
364template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
367 while (set != m_parents[set]) {
368 set = m_parents[set];
373template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
376 return m_parents[set];
380template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
384#ifdef OGDF_DISJOINT_SETS_INTERMEDIATE_PARENT_CHECK
385 if (m_parents[
set1] == m_parents[
set2]) {
398template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
402#ifdef OGDF_DISJOINT_SETS_INTERMEDIATE_PARENT_CHECK
403 if (m_parents[
set1] == m_parents[
set2]) {
409 int parent = m_parents[set];
410 m_parents[set] = root;
411 while (set != parent) {
412 if (parent ==
set1) {
413 m_parents[root] =
set1;
417 parent = m_parents[set];
418 m_parents[set] = root;
422 parent = m_parents[set];
424 if (parent == root) {
427 m_parents[set] = root;
432 parent = m_parents[set];
436template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
466template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
471#ifdef OGDF_DISJOINT_SETS_INTERMEDIATE_PARENT_CHECK
472 if (m_parents[
set1] == m_parents[
set2]) {
485 set = m_parents[set];
486 int parent = m_parents[set];
494 m_parents[
set1] = parent;
499 parent = m_parents[set];
502 m_parents[set] = root;
507 parent = m_parents[set];
508 }
else if (parent > root) {
509 m_parents[root] = parent;
510 m_parents[
set1] = parent;
511 m_parents[
set2] = parent;
519template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
528 if (m_parameters[
p_r_x] <= m_parameters[
p_r_y]) {
531 m_parameters[
p_r_y]++;
553template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
565template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
579 m_parameters[
set2]++;
584template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
601template<LinkOptions linkOption, CompressionOptions compressionOption, InterleavingOptions
interleavingOption>
A Union/Find data structure for maintaining disjoint sets.
bool quickUnion(int set1, int set2)
Unions the maximal disjoint sets containing set1 and set2.
int makeSet()
Initializes a singleton set.
int getRepresentative(int set) const
Returns the id of the largest superset of set.
void init()
Resets the DisjointSets structure to be empty, preserving the previous value of maxNumberOfElements.
int m_numberOfElements
Current number of elements.
bool quickUnion(disjoint_sets::LinkOption< LinkOptions::Index >, disjoint_sets::InterleavingOption< InterleavingOptions::Rem >, int set1, int set2)
int find(int set)
Returns the id of the largest superset of set and compresses the path according to CompressionOptions...
DisjointSets & operator=(const DisjointSets &)=delete
int m_numberOfSets
Current number of disjoint sets.
int getNumberOfSets()
Returns the current number of disjoint sets.
int find(disjoint_sets::CompressionOption< CompressionOptions::PathCompression >, int set)
int link(disjoint_sets::LinkOption< LinkOptions::Naive >, int set1, int set2)
DisjointSets(int maxNumberOfElements=(1<< 15))
Creates an empty DisjointSets structure.
void init(int maxNumberOfElements)
Resets the DisjointSets structure to be empty, also changing the expected number of elements.
int * m_parameters
Maps set id to rank/size.
int getNumberOfElements()
Returns the current number of elements.
int * m_parents
Maps set id to parent set id.
DisjointSets(const DisjointSets &)=delete
int link(int set1, int set2)
Unions set1 and set2.
int linkPure(int set1, int set2)
Unions set1 and set2 w/o decreasing the numberOfSets.
int * m_siblings
Maps set id to sibling set id.
int m_maxNumberOfElements
Maximum number of elements (array size) adjusted dynamically.
Definition of exception classes.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.
LinkOptions
Defines options for linking two sets.
@ Index
Link by index (default)
InterleavingOptions
Defines options for interleaving find/link operations in quickUnion.
@ Type0Reversal
Interleaved Reversal of Type 0 (only compatible with LinkOptions::Naive)
@ SplittingCompression
Interleaved Path Splitting Path Compression (only compatible with LinkOptions::Index)
@ Tarjan
Tarjan's and van Leeuwen's Algorithm (only compatible with LinkOptions::Rank)
@ Disabled
No Interleaving (default)
@ Rem
Rem's Algorithm (only compatible with LinkOptions::Index)
CompressionOptions
Defines options for compression search paths.
@ PathHalving
Path Halving.
@ PathSplitting
Path Splitting (default)
@ Disabled
No Compression.
@ Type1Reversal
Reversal of type 1.
@ PathCompression
Path Compression.