GEOS 3.14.0dev
UnionFind.h
1/**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (C) 2020-2021 Daniel Baston
7 *
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Public Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
12 *
13 **********************************************************************/
14
15#pragma once
16
17#include <algorithm>
18#include <numeric>
19#include <vector>
20
21#include <geos/export.h>
22#include <geos/operation/cluster/Clusters.h>
23
24namespace geos {
25namespace operation {
26namespace cluster {
27
32class GEOS_DLL UnionFind {
33
34public:
39 explicit UnionFind(size_t n) :
40 clusters(n),
41 sizes(n),
42 num_clusters(n) {
43 std::iota(clusters.begin(), clusters.end(), 0);
44 std::fill(sizes.begin(), sizes.end(), 1);
45 }
46
47 // Are two elements in the same cluster?
48 bool same(size_t i, size_t j) {
49 return i == j || (find(i) == find(j));
50 }
51
52 // Are two elements in a different cluster?
53 bool different(size_t i, size_t j) {
54 return !same(i, j);
55 }
56
62 size_t find(size_t i) {
63 size_t root = i;
64
65 while(clusters[root] != root) {
66 root = clusters[root];
67 }
68
69 while (i != root) {
70 size_t next = clusters[i];
71 clusters[i] = root;
72 i = next;
73 }
74
75 return i;
76 }
77
83 void join(size_t i, size_t j) {
84 auto a = find(i);
85 auto b = find(j);
86
87 if (a == b) {
88 return;
89 }
90
91 if ((sizes[b] > sizes[a]) || (sizes[a] == sizes[b] && b <= a)) {
92 std::swap(a, b);
93 }
94
95 clusters[a] = clusters[b];
96 sizes[b] += sizes[a];
97 sizes[a] = 0;
98
99 num_clusters--;
100 }
101
102 size_t getNumClusters() const {
103 return num_clusters;
104 }
105
106 template<typename T>
107 void sortByCluster(T begin, T end) {
108 std::sort(begin, end, [this](size_t a, size_t b) {
109 return find(a) < find(b);
110 });
111 }
112
117 Clusters getClusters();
118
124 Clusters getClusters(std::vector<size_t> elems);
125
126private:
127 std::vector<size_t> clusters;
128 std::vector<size_t> sizes;
129 size_t num_clusters;
130};
131
132}
133}
134}
Definition UnionFind.h:32
Clusters getClusters(std::vector< size_t > elems)
UnionFind(size_t n)
Definition UnionFind.h:39
size_t find(size_t i)
Definition UnionFind.h:62
void join(size_t i, size_t j)
Definition UnionFind.h:83
Basic namespace for all GEOS functionalities.
Definition geos.h:39