GEOS 3.13.1
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#ifndef GEOS_OPERATION_CLUSTER_UNIONFIND
16#define GEOS_OPERATION_CLUSTER_UNIONFIND
17
18#include <algorithm>
19#include <numeric>
20#include <vector>
21
22#include <geos/export.h>
23#include <geos/operation/cluster/Clusters.h>
24
25namespace geos {
26namespace operation {
27namespace cluster {
28
33class GEOS_DLL UnionFind {
34
35public:
40 explicit UnionFind(size_t n) :
41 clusters(n),
42 sizes(n),
43 num_clusters(n) {
44 std::iota(clusters.begin(), clusters.end(), 0);
45 std::fill(sizes.begin(), sizes.end(), 1);
46 }
47
48 // Are two elements in the same cluster?
49 bool same(size_t i, size_t j) {
50 return i == j || (find(i) == find(j));
51 }
52
53 // Are two elements in a different cluster?
54 bool different(size_t i, size_t j) {
55 return !same(i, j);
56 }
57
63 size_t find(size_t i) {
64 size_t root = i;
65
66 while(clusters[root] != root) {
67 root = clusters[root];
68 }
69
70 while (i != root) {
71 size_t next = clusters[i];
72 clusters[i] = root;
73 i = next;
74 }
75
76 return i;
77 }
78
84 void join(size_t i, size_t j) {
85 auto a = find(i);
86 auto b = find(j);
87
88 if (a == b) {
89 return;
90 }
91
92 if ((sizes[b] > sizes[a]) || (sizes[a] == sizes[b] && b <= a)) {
93 std::swap(a, b);
94 }
95
96 clusters[a] = clusters[b];
97 sizes[b] += sizes[a];
98 sizes[a] = 0;
99
100 num_clusters--;
101 }
102
103 size_t getNumClusters() const {
104 return num_clusters;
105 }
106
107 template<typename T>
108 void sortByCluster(T begin, T end) {
109 std::sort(begin, end, [this](size_t a, size_t b) {
110 return find(a) < find(b);
111 });
112 }
113
118 Clusters getClusters();
119
125 Clusters getClusters(std::vector<size_t> elems);
126
127private:
128 std::vector<size_t> clusters;
129 std::vector<size_t> sizes;
130 size_t num_clusters;
131};
132
133}
134}
135}
136
137#endif
Definition UnionFind.h:33
Clusters getClusters(std::vector< size_t > elems)
UnionFind(size_t n)
Definition UnionFind.h:40
size_t find(size_t i)
Definition UnionFind.h:63
void join(size_t i, size_t j)
Definition UnionFind.h:84
Basic namespace for all GEOS functionalities.
Definition geos.h:39