From c168638060c2755ef5e5450b8e827a4f44afa41b Mon Sep 17 00:00:00 2001 From: Leo Yang Date: Fri, 24 Jan 2020 23:14:25 -0600 Subject: [PATCH 1/2] feat: add union find algorithm (aka disjoint set) --- data_structure/disjoint_set.cpp | 69 +++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 data_structure/disjoint_set.cpp diff --git a/data_structure/disjoint_set.cpp b/data_structure/disjoint_set.cpp new file mode 100644 index 000000000..de5d1c0e0 --- /dev/null +++ b/data_structure/disjoint_set.cpp @@ -0,0 +1,69 @@ +#include +#include +using namespace std; + +vector root, rnk; + +void CreateSet(int n){ + root = vector (n+1); + rnk = vector (n+1, 1); + + for(int i = 1; i <= n; ++ i) { + root[i] = i; + } +} + +int Find(int x) { + if (root[x] == x) { + return x; + } + return root[x] = Find(root[x]); +} + +bool InSameUnion(int x, int y) { + return Find(x) == Find(y); +} + +void Union(int x, int y) { + int a = Find(x), b = Find(y); + if(a != b) { + if (rnk[a] < rnk[b]) { + root[a] = b; + } else if (rnk[a] > rnk[b]) { + root[b] = a; + } else { + root[a] = b; + ++ rnk[b]; + } + } +} + +int main() { + + // tests CreateSet & Find + + int n = 100; + CreateSet(n); + + for (int i = 1; i <= 100; ++ i) { + if (root[i] != i) { + cout << "Fail" << endl; + break; + } + } + + // tests InSameUnion & Union + + cout << "1 and 2 are initially not in the same subset" << endl; + if (InSameUnion(1, 2)) { + cout << "Fail" << endl; + } + + Union(1, 2); + cout << "1 and 2 are now in the same subset" << endl; + if (!InSameUnion(1, 2)) { + cout << "Fail" << endl; + } + + return 0; +} From 1c5b12323ab1dc3e5f2d8d7c108c267b0f801ccf Mon Sep 17 00:00:00 2001 From: Leo Yang Date: Fri, 24 Jan 2020 23:22:08 -0600 Subject: [PATCH 2/2] feat: add union find algorithm (aka disjoint set) --- data_structure/disjoint_set.cpp | 93 ++++++++++++++++----------------- 1 file changed, 44 insertions(+), 49 deletions(-) diff --git a/data_structure/disjoint_set.cpp b/data_structure/disjoint_set.cpp index de5d1c0e0..71b220ab9 100644 --- a/data_structure/disjoint_set.cpp +++ b/data_structure/disjoint_set.cpp @@ -1,69 +1,64 @@ #include #include -using namespace std; + +using std::cout; +using std::endl; +using std::vector; vector root, rnk; -void CreateSet(int n){ - root = vector (n+1); - rnk = vector (n+1, 1); - - for(int i = 1; i <= n; ++ i) { - root[i] = i; - } +void CreateSet(int n) { + root = vector (n+1); + rnk = vector (n+1, 1); + for (int i = 1; i <= n; ++i) { + root[i] = i; + } } int Find(int x) { - if (root[x] == x) { - return x; - } - return root[x] = Find(root[x]); + if (root[x] == x) { + return x; + } + return root[x] = Find(root[x]); } bool InSameUnion(int x, int y) { - return Find(x) == Find(y); + return Find(x) == Find(y); } void Union(int x, int y) { - int a = Find(x), b = Find(y); - if(a != b) { - if (rnk[a] < rnk[b]) { - root[a] = b; - } else if (rnk[a] > rnk[b]) { - root[b] = a; - } else { - root[a] = b; - ++ rnk[b]; - } + int a = Find(x), b = Find(y); + if (a != b) { + if (rnk[a] < rnk[b]) { + root[a] = b; + } else if (rnk[a] > rnk[b]) { + root[b] = a; + } else { + root[a] = b; + ++rnk[b]; } + } } int main() { - - // tests CreateSet & Find - - int n = 100; - CreateSet(n); - - for (int i = 1; i <= 100; ++ i) { - if (root[i] != i) { - cout << "Fail" << endl; - break; - } + // tests CreateSet & Find + int n = 100; + CreateSet(n); + for (int i = 1; i <= 100; ++i) { + if (root[i] != i) { + cout << "Fail" << endl; + break; } - - // tests InSameUnion & Union - - cout << "1 and 2 are initially not in the same subset" << endl; - if (InSameUnion(1, 2)) { - cout << "Fail" << endl; - } - - Union(1, 2); - cout << "1 and 2 are now in the same subset" << endl; - if (!InSameUnion(1, 2)) { - cout << "Fail" << endl; - } - - return 0; + } + // tests InSameUnion & Union + cout << "1 and 2 are initially not in the same subset" << endl; + if (InSameUnion(1, 2)) { + cout << "Fail" << endl; + } + Union(1, 2); + cout << "1 and 2 are now in the same subset" << endl; + if (!InSameUnion(1, 2)) { + cout << "Fail" << endl; + } + return 0; }