Skip to content

Commit

Permalink
1.5 union-find
Browse files Browse the repository at this point in the history
  • Loading branch information
landerrosette committed Sep 17, 2024
1 parent 516b76a commit eaa4fb9
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,8 @@ add_executable(algs4
PrimMST.cpp
PrimMST.h
tests/testGraph.cpp
UF.cpp
UF.h
tests/testUF.h
tests/testUF.cpp
)
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ incorporating modern C++ practices.

## List of Algorithms

### Fundamentals

- **1.5** Union-find: [UF.h](UF.h) | [UF.cpp](UF.cpp)

### Sorting

- **2.1** Selection sort: [Selection.h](Selection.h)
Expand Down
27 changes: 27 additions & 0 deletions UF.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "UF.h"

UF::UF(int N) : id(N), sz(N), count_(N) {
for (int i = 0; i < N; i++) {
id[i] = i;
sz[i] = 1;
}
}

int UF::find(int p) const {
while (p != id[p]) p = id[p];
return p;
}

void UF::unionize(int p, int q) {
int i = find(p);
int j = find(q);
if (i == j) return;
if (sz[i] < sz[j]) {
id[i] = j;
sz[j] += sz[i];
} else {
id[j] = i;
sz[i] += sz[j];
}
--count_;
}
25 changes: 25 additions & 0 deletions UF.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef UF_H
#define UF_H
#include <vector>


class UF {
private:
std::vector<int> id; // 父链接数组(以触点为索引)
std::vector<int> sz; // 各个根节点对应的分量的大小(以触点为索引)
int count_; // 分量数量

public:
UF(int N);

int count() const { return count_; }

bool connected(int p, int q) const { return find(p) == find(q); }

int find(int p) const;

void unionize(int p, int q);
};


#endif //UF_H
12 changes: 12 additions & 0 deletions data/tinyUF.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
10
4 3
3 8
6 5
9 4
2 1
8 9
5 0
7 2
6 1
1 0
6 7
11 changes: 9 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,21 @@
#include "Topological.h"
#include "KosarajuSCC.h"
#include "PrimMST.h"
#include "tests/testUF.h"
#include "tests/testSort.h"
#include "tests/testPQ.h"
#include "tests/testST.h"
#include "tests/testGraph.h"

int main(int argc, char* argv[]) {
std::filesystem::path dataFilePath(argv[1]);
if (dataFilePath.filename() == "words3.txt") {
if (argc < 2) {
// 测试union-find
// ./algs4 < ../data/tinyUF.txt
std::cout << "Testing 1.5 union-find" << "\n";
std::cout << "================================================" << "\n";
testUF();
std::cout << "================================================" << "\n";
} else if (std::filesystem::path dataFilePath(argv[1]); dataFilePath.filename() == "words3.txt") {
// 测试排序算法
// ./algs4 ../data/words3.txt
std::cout << "Testing 2.1 selection sort" << "\n";
Expand Down
16 changes: 16 additions & 0 deletions tests/testUF.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "testUF.h"
#include "UF.h"
#include <iostream>

void testUF() {
UF uf([]() {
int N;
return std::cin >> N, N;
}());
for (int p, q; std::cin >> p >> q;) {
if (uf.connected(p, q)) continue;
uf.unionize(p, q);
std::cout << p << " " << q << "\n";
}
std::cout << uf.count() << " components" << "\n";
}
6 changes: 6 additions & 0 deletions tests/testUF.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef TESTUF_H
#define TESTUF_H

void testUF();

#endif //TESTUF_H

0 comments on commit eaa4fb9

Please sign in to comment.