Improve complexity of union_find, better explain complexity.
Summary: Old union find implementation was not true about it's complexity. Take a look at http://www.brpreiss.com/books/opus4/html/page411.html#theoremsetsi. Test Plan: Run union_find in tests. Reviewers: mislav.bradac, buda Reviewed By: mislav.bradac Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D51
This commit is contained in:
parent
2cee2cf480
commit
40aa500a88
@ -6,7 +6,7 @@
|
|||||||
template <class uintXX_t = uint32_t>
|
template <class uintXX_t = uint32_t>
|
||||||
/**
|
/**
|
||||||
* UnionFind data structure. Provides means of connectivity
|
* UnionFind data structure. Provides means of connectivity
|
||||||
* setting and checking in logarithmic complexity. Memory
|
* setting and checking in O(alpha(n)) amortized complexity. Memory
|
||||||
* complexity is linear.
|
* complexity is linear.
|
||||||
*/
|
*/
|
||||||
class UnionFind {
|
class UnionFind {
|
||||||
@ -16,15 +16,15 @@ class UnionFind {
|
|||||||
*
|
*
|
||||||
* @param n Number of elements in the data structure.
|
* @param n Number of elements in the data structure.
|
||||||
*/
|
*/
|
||||||
UnionFind(uintXX_t n) : set_count(n), count(n), parent(n) {
|
UnionFind(uintXX_t n) : set_count(n), rank(n), parent(n) {
|
||||||
for (auto i = 0; i < n; ++i) count[i] = 1, parent[i] = i;
|
for (auto i = 0; i < n; ++i) rank[i] = 0, parent[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects two elements (and thereby the sets they belong
|
* Connects two elements (and thereby the sets they belong
|
||||||
* to). If they are already connected the function has no effect.
|
* to). If they are already connected the function has no effect.
|
||||||
*
|
*
|
||||||
* Has O(alpha(n)) time complexity.
|
* Has O(alpha(n)) amortized time complexity.
|
||||||
*
|
*
|
||||||
* @param p First element.
|
* @param p First element.
|
||||||
* @param q Second element.
|
* @param q Second element.
|
||||||
@ -36,18 +36,21 @@ class UnionFind {
|
|||||||
// if roots are equal, we don't have to do anything
|
// if roots are equal, we don't have to do anything
|
||||||
if (rp == rq) return;
|
if (rp == rq) return;
|
||||||
|
|
||||||
// merge the smaller subtree to the root of the larger subtree
|
// merge the subtree with the smaller rank to the root of the subtree with
|
||||||
if (count[rp] < count[rq])
|
// the larger rank
|
||||||
parent[rp] = rq, count[rp] += count[rp];
|
if (rank[rp] < rank[rq])
|
||||||
|
parent[rp] = rq;
|
||||||
|
else if (rank[rp] > rank[rq])
|
||||||
|
parent[rq] = rp;
|
||||||
else
|
else
|
||||||
parent[rq] = rp, count[rp] += count[rq];
|
parent[rq] = rp, rank[rp] += 1;
|
||||||
|
|
||||||
// update the number of groups
|
// update the number of groups
|
||||||
set_count--;
|
set_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if two elements are connected. Has O(alpha(n)) time
|
* Indicates if two elements are connected. Has amortized O(alpha(n)) time
|
||||||
* complexity.
|
* complexity.
|
||||||
*
|
*
|
||||||
* @param p First element.
|
* @param p First element.
|
||||||
@ -66,8 +69,8 @@ class UnionFind {
|
|||||||
private:
|
private:
|
||||||
uintXX_t set_count;
|
uintXX_t set_count;
|
||||||
|
|
||||||
// array of subtree counts
|
// array of subtree ranks
|
||||||
std::vector<uintXX_t> count;
|
std::vector<uintXX_t> rank;
|
||||||
|
|
||||||
// array of tree indices
|
// array of tree indices
|
||||||
std::vector<uintXX_t> parent;
|
std::vector<uintXX_t> parent;
|
||||||
|
Loading…
Reference in New Issue
Block a user