// Copyright (C) 2011 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_DISJOINT_SUBsETS_Hh_ #define DLIB_DISJOINT_SUBsETS_Hh_ #include "disjoint_subsets_abstract.h" #include #include "../algs.h" namespace dlib { // ---------------------------------------------------------------------------------------- class disjoint_subsets { public: void clear ( ) noexcept { items.clear(); } void set_size ( unsigned long new_size ) { items.resize(new_size); for (unsigned long i = 0; i < items.size(); ++i) { items[i].parent = i; items[i].rank = 0; } } size_t size ( ) const noexcept { return items.size(); } unsigned long find_set ( unsigned long item ) const { // make sure requires clause is not broken DLIB_ASSERT(item < size(), "\t unsigned long disjoint_subsets::find_set()" << "\n\t item must be less than size()" << "\n\t item: " << item << "\n\t size(): " << size() << "\n\t this: " << this ); if (items[item].parent == item) { return item; } else { // find root of item unsigned long x = item; do { x = items[x].parent; } while (items[x].parent != x); // do path compression const unsigned long root = x; x = item; while (items[x].parent != x) { const unsigned long prev = x; x = items[x].parent; items[prev].parent = root; } return root; } } unsigned long merge_sets ( unsigned long a, unsigned long b ) { // make sure requires clause is not broken DLIB_ASSERT(a != b && a < size() && b < size() && find_set(a) == a && find_set(b) == b, "\t unsigned long disjoint_subsets::merge_sets(a,b)" << "\n\t invalid arguments were given to this function" << "\n\t a: " << a << "\n\t b: " << b << "\n\t size(): " << size() << "\n\t find_set(a): " << find_set(a) << "\n\t find_set(b): " << find_set(b) << "\n\t this: " << this ); if (items[a].rank > items[b].rank) { items[b].parent = a; return a; } else { items[a].parent = b; if (items[a].rank == items[b].rank) { items[b].rank = items[b].rank + 1; } return b; } } private: /* See the book Introduction to Algorithms by Cormen, Leiserson, Rivest and Stein for a discussion of how this algorithm works. */ struct data { unsigned long rank; unsigned long parent; }; mutable std::vector items; }; // ---------------------------------------------------------------------------------------- } #endif // DLIB_DISJOINT_SUBsETS_Hh_