diff --git a/data_structures/dsu_path_compression.cpp b/data_structures/dsu_path_compression.cpp index bbdc2a9a9..f13f9b10b 100644 --- a/data_structures/dsu_path_compression.cpp +++ b/data_structures/dsu_path_compression.cpp @@ -1,25 +1,26 @@ /** * @file - * @brief [DSU (Disjoint sets)](https://en.wikipedia.org/wiki/Disjoint-set-data_structure) + * @brief [DSU (Disjoint + * sets)](https://en.wikipedia.org/wiki/Disjoint-set-data_structure) * @details * It is a very powerful data structure that keeps track of different - * clusters(sets) of elements, these sets are disjoint(doesnot have a common element). - * Disjoint sets uses cases : for finding connected components in a graph, - * used in Kruskal's algorithm for finding Minimum Spanning tree. + * clusters(sets) of elements, these sets are disjoint(doesnot have a common + * element). Disjoint sets uses cases : for finding connected components in a + * graph, used in Kruskal's algorithm for finding Minimum Spanning tree. * Operations that can be performed: * 1) UnionSet(i,j): add(element i and j to the set) * 2) findSet(i): returns the representative of the set to which i belogngs to. - * 3) get_max(i),get_min(i) : returns the maximum and minimum - * Below is the class-based approach which uses the heuristic of path compression. - * Using path compression in findSet(i),we are able to get to the representative of i - * in O(1) time. + * 3) get_max(i),get_min(i) : returns the maximum and minimum + * Below is the class-based approach which uses the heuristic of path + * compression. Using path compression in findSet(i),we are able to get to the + * representative of i in O(1) time. * @author [AayushVyasKIIT](https://github.com/AayushVyasKIIT) * @see dsu_union_rank.cpp */ +#include /// for assert #include /// for IO operations #include /// for std::vector -#include /// for assert using std::cout; using std::endl; @@ -29,139 +30,136 @@ using std::vector; * @brief Disjoint sets union data structure, class based representation. * @param n number of elements */ -class dsu{ - private: - vector p; /// depth; /// setSize;/// maxElement;/// minElement;/// p; ///< keeps track of the parent of ith element + vector depth; ///< tracks the depth(rank) of i in the tree + vector setSize; ///< size of each chunk(set) + vector maxElement; /// minElement; /// depth[y]) { + std::swap(x, y); + } + // making the shallower root's parent the deeper root + p[x] = y; - //always keeping the min as x - //shallow tree - if(depth[x]>depth[y]){ - std::swap(x,y); - } - //making the shallower root's parent the deeper root - p[x] = y; - - //if same depth then increase one's depth - if(depth[x] == depth[y]){ - depth[y]++; - } - //total size of the resultant set. - setSize[y] += setSize[x]; - //changing the maximum elements - maxElement[y] = std::max(maxElement[x],maxElement[y]); - minElement[y] = std::min(minElement[x],minElement[y]); + // if same depth then increase one's depth + if (depth[x] == depth[y]) { + depth[y]++; } - /** - * @brief A utility function which check whether i and j belongs to - * same set or not - * @param i element of some set - * @param j element of some set - * @returns `true` if element `i` and `j` ARE in the same set - * @returns `false` if element `i` and `j` are NOT in same set - */ - bool isSame(uint64_t i,uint64_t j){ - if(findSet(i) == findSet(j)){ - return true; - } - return false; + // total size of the resultant set. + setSize[y] += setSize[x]; + // changing the maximum elements + maxElement[y] = std::max(maxElement[x], maxElement[y]); + minElement[y] = std::min(minElement[x], minElement[y]); + } + /** + * @brief A utility function which check whether i and j belongs to + * same set or not + * @param i element of some set + * @param j element of some set + * @returns `true` if element `i` and `j` ARE in the same set + * @returns `false` if element `i` and `j` are NOT in same set + */ + bool isSame(uint64_t i, uint64_t j) { + if (findSet(i) == findSet(j)) { + return true; } - /** - * @brief prints the minimum, maximum and size of the set to which i belongs to - * @param i element of some set - * @returns void - */ - vector get(uint64_t i){ - vector ans; - ans.push_back(get_min(i)); - ans.push_back(get_max(i)); - ans.push_back(size(i)); - return ans; - - } - /** - * @brief A utility function that returns the size of the set to which i belongs to - * @param i element of some set - * @returns size of the set to which i belongs to - */ - uint64_t size(uint64_t i){ - return setSize[findSet(i)]; - } - /** - * @brief A utility function that returns the max element of the set to which i belongs to - * @param i element of some set - * @returns maximum of the set to which i belongs to - */ - uint64_t get_max(uint64_t i){ - return maxElement[findSet(i)]; - } - /** - * @brief A utility function that returns the min element of the set to which i belongs to - * @param i element of some set - * @returns minimum of the set to which i belongs to - */ - uint64_t get_min(uint64_t i){ - return minElement[findSet(i)]; - } - + return false; + } + /** + * @brief prints the minimum, maximum and size of the set to which i belongs + * to + * @param i element of some set + * @returns void + */ + vector get(uint64_t i) { + vector ans; + ans.push_back(get_min(i)); + ans.push_back(get_max(i)); + ans.push_back(size(i)); + return ans; + } + /** + * @brief A utility function that returns the size of the set to which i + * belongs to + * @param i element of some set + * @returns size of the set to which i belongs to + */ + uint64_t size(uint64_t i) { return setSize[findSet(i)]; } + /** + * @brief A utility function that returns the max element of the set to + * which i belongs to + * @param i element of some set + * @returns maximum of the set to which i belongs to + */ + uint64_t get_max(uint64_t i) { return maxElement[findSet(i)]; } + /** + * @brief A utility function that returns the min element of the set to + * which i belongs to + * @param i element of some set + * @returns minimum of the set to which i belongs to + */ + uint64_t get_min(uint64_t i) { return minElement[findSet(i)]; } }; /** * @brief Self-implementation Test case #1 @@ -169,16 +167,16 @@ class dsu{ */ static void test1() { /* the minimum, maximum and size of the set*/ - uint64_t n = 10;///< number of items - dsu d(n+1);///< object of class disjoint sets - //set 1 - d.UnionSet(1,2); //performs union operation on 1 and 2 - d.UnionSet(1,4); //performs union operation on 1 and 4 - vector ans = {1,4,3}; - for(uint64_t i=0;i ans = {1, 4, 3}; + for (uint64_t i = 0; i < ans.size(); i++) { + assert(d.get(4).at(i) == ans[i]); // makes sure algorithm works fine } - cout << "Test case# 1: passed"< ans = {3,7,4}; - for(uint64_t i=0;i ans = {3, 7, 4}; + for (uint64_t i = 0; i < ans.size(); i++) { + assert(d.get(3).at(i) == ans[i]); // makes sure algorithm works fine } - cout << "Test case# 2: passed"<