Skip to content

Commit bcf0d9f

Browse files
author
tianqing.liang
committed
并查集,AVL树
1 parent 6485bde commit bcf0d9f

17 files changed

+30595
-5
lines changed

11-Set-And-Map/BST.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ class BST<T extends Comparable<T>> {
262262
root = _removeNode(root!, e);
263263
}
264264

265-
_removeNode(_Node node, T e){
265+
_removeNode(_Node node, T? e){
266266
if( node == null )
267267
return null;
268268

11-Set-And-Map/BSTMap.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ class BSTMap<K extends Comparable<K>, V> extends Map<K, V> {
1616
@override
1717
add(key, value) {
1818
// TODO: implement add
19-
root = _addNode(root!, key, value);
19+
root = _addNode(root, key, value);
2020
}
2121

22-
_Node _addNode(_Node node, K key, V value) {
22+
_Node _addNode(_Node? node, K key, V value) {
2323
if (node == null) {
2424
size = size! + 1;
2525
return _Node(key, value);

11-Set-And-Map/Main.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:io';
22
import 'dart:convert';
33
import 'FileOperator.dart';
44
import 'BSTSet.dart';
5+
import 'BST.dart';
56

67
void main() async{
78

18-Union-Find/Main.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import 'UnionFind1.dart';
2+
import 'UnionFind2.dart';
3+
import 'UnionFind3.dart';
4+
import 'UnionFind4.dart';
5+
import 'UnionFind5.dart';
6+
import 'UnionFind6.dart';
7+
import 'dart:math';
8+
import 'UF.dart';
9+
10+
double testUF(UF uf, int m){
11+
12+
int? size = uf.getSize();
13+
Random random = new Random();
14+
15+
var now = new DateTime.now();
16+
num startTime = now.millisecondsSinceEpoch;
17+
18+
19+
for(int i = 0 ; i < m ; i ++){
20+
int a = random.nextInt(size!);
21+
int b = random.nextInt(size);
22+
uf.unionElements(a, b);
23+
}
24+
25+
for(int i = 0 ; i < m ; i ++){
26+
int a = random.nextInt(size!);
27+
int b = random.nextInt(size);
28+
uf.isConnected(a, b);
29+
}
30+
31+
var endNow = new DateTime.now();
32+
num endTime = endNow.millisecondsSinceEpoch;
33+
34+
double time = (endTime - startTime) / 1000.0;
35+
return time;
36+
}
37+
38+
void main(){
39+
int size = 10000000;
40+
int m = 10000000;
41+
42+
UnionFind3 uf3 = new UnionFind3(size);
43+
print("UnionFind3 : ${testUF(uf3, m)} s");
44+
45+
UnionFind4 uf4 = new UnionFind4(size);
46+
print("UnionFind4 : ${testUF(uf4, m)} s");
47+
48+
UnionFind5 uf5 = new UnionFind5(size);
49+
print("UnionFind5 : ${testUF(uf5, m)} s");
50+
51+
UnionFind6 uf6 = new UnionFind6(size);
52+
print("UnionFind6 : ${testUF(uf6, m)} s");
53+
54+
}

18-Union-Find/UF.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
abstract class UF {
2+
int? getSize();
3+
bool isConnected(int p, int q);
4+
void unionElements(int p, int q);
5+
6+
}

18-Union-Find/UnionFind1.dart

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import 'UF.dart';
2+
3+
/**
4+
* 第一版并查集
5+
*/
6+
class UnionFind1 extends UF {
7+
8+
List? id;
9+
10+
UnionFind1(int size) {
11+
12+
id = List.filled(size, num , growable: false);
13+
// 初始化, 每一个id[i]指向自己, 没有合并的元素
14+
for (var i = 0; i < size; i++){
15+
id![i] = i;
16+
}
17+
}
18+
19+
@override
20+
int? getSize(){
21+
return id!.length;
22+
}
23+
24+
// 查找元素p所对应的集合编号
25+
// O(1)复杂度
26+
int find(int p) {
27+
if(p < 0 || p >= id!.length){
28+
throw new Exception("p is out of bound.");
29+
}
30+
return id![p];
31+
}
32+
33+
// 查看元素p和元素q是否所属一个集合
34+
// O(1)复杂度
35+
@override
36+
bool isConnected(int p, int q) {
37+
return find(p) == find(q);
38+
}
39+
40+
// 合并元素p和元素q所属的集合
41+
// O(n) 复杂度
42+
@override
43+
unionElements(int p, int q) {
44+
45+
int pID = find(p);
46+
int qID = find(q);
47+
48+
if (pID == qID){
49+
return;
50+
}
51+
// 合并过程需要遍历一遍所有元素, 将两个元素的所属集合编号合并
52+
for (var i = 0; i < id!.length; i++){
53+
if (id![i] == pID){
54+
id![i] = qID;
55+
}
56+
}
57+
}
58+
}

18-Union-Find/UnionFind2.dart

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import 'UF.dart';
2+
/**
3+
* 第二版并查集
4+
*/
5+
class UnionFind2 extends UF {
6+
7+
// 使用一个数组构建一棵指向父节点的树
8+
// parent[i]表示第一个元素所指向的父节点
9+
List? parent;
10+
11+
// 构造函数
12+
UnionFind2(int size){
13+
14+
parent = List.filled(size, num,growable: false);
15+
// 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合
16+
for( var i = 0 ; i < size ; i ++ ){
17+
parent![i] = i;
18+
}
19+
}
20+
21+
@override
22+
int? getSize(){
23+
return parent!.length;
24+
}
25+
26+
// 查找过程, 查找元素p所对应的集合编号
27+
// O(h)复杂度, h为树的高度
28+
int find(int p){
29+
if(p < 0 || p >= parent!.length)
30+
throw new Exception("p is out of bound.");
31+
32+
// 不断去查询自己的父亲节点, 直到到达根节点
33+
// 根节点的特点: parent[p] == p
34+
while(p != parent![p]){
35+
p = parent![p];
36+
}
37+
return p;
38+
}
39+
40+
// 查看元素p和元素q是否所属一个集合
41+
// O(h)复杂度, h为树的高度
42+
@override
43+
bool isConnected( int p , int q ){
44+
return find(p) == find(q);
45+
}
46+
47+
// 合并元素p和元素q所属的集合
48+
// O(h)复杂度, h为树的高度
49+
@override
50+
unionElements(int p, int q){
51+
52+
int pRoot = find(p);
53+
int qRoot = find(q);
54+
55+
if( pRoot == qRoot ) {
56+
return;
57+
}
58+
parent![pRoot] = qRoot;
59+
}
60+
}

18-Union-Find/UnionFind3.dart

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import 'UF.dart';
2+
3+
/**
4+
* 第三版 并查集
5+
*/
6+
class UnionFind3 extends UF {
7+
List? parent; // parent[i]表示第一个元素所指向的父节点
8+
List? sz; // sz[i]表示以i为根的集合中元素个数
9+
10+
// 构造函数
11+
UnionFind3(int size) {
12+
parent = List.filled(size, num, growable: false);
13+
sz = List.filled(size, num, growable: false);
14+
15+
// 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合
16+
for (int i = 0; i < size; i++) {
17+
parent![i] = i;
18+
sz![i] = 1;
19+
}
20+
}
21+
22+
@override
23+
int? getSize() {
24+
return parent!.length;
25+
}
26+
27+
// 查找过程, 查找元素p所对应的集合编号
28+
// O(h)复杂度, h为树的高度
29+
int find(int p) {
30+
if (p < 0 || p >= parent!.length) {
31+
throw new Exception("p is out of bound.");
32+
}
33+
34+
// 不断去查询自己的父亲节点, 直到到达根节点
35+
// 根节点的特点: parent[p] == p
36+
while (p != parent![p]) {
37+
p = parent![p];
38+
}
39+
return p;
40+
}
41+
42+
// 查看元素p和元素q是否所属一个集合
43+
// O(h)复杂度, h为树的高度
44+
@override
45+
bool isConnected(int p, int q) {
46+
return find(p) == find(q);
47+
}
48+
49+
// 合并元素p和元素q所属的集合
50+
// O(h)复杂度, h为树的高度
51+
@override
52+
unionElements(int p, int q) {
53+
int pRoot = find(p);
54+
int qRoot = find(q);
55+
56+
if (pRoot == qRoot) return;
57+
58+
// 根据两个元素所在树的元素个数不同判断合并方向
59+
// 将元素个数少的集合合并到元素个数多的集合上
60+
if (sz![pRoot] < sz![qRoot]) {
61+
parent![pRoot] = qRoot;
62+
sz![qRoot] += sz![pRoot];
63+
} else {
64+
// sz[qRoot] <= sz[pRoot]
65+
parent![qRoot] = pRoot;
66+
sz![pRoot] += sz![qRoot];
67+
}
68+
}
69+
}

18-Union-Find/UnionFind4.dart

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import 'UF.dart';
2+
3+
/**
4+
* 第四版并查集
5+
*/
6+
class UnionFind4 implements UF {
7+
List? rank; // rank[i]表示以i为根的集合所表示的树的层数
8+
List? parent; // parent[i]表示第i个元素所指向的父节点
9+
10+
// 构造函数
11+
UnionFind4(int size) {
12+
rank = List.filled(size, num, growable: false);
13+
parent = List.filled(size, num, growable: false);
14+
15+
// 初始化, 每一个parent[i]指向自己, 表示每一个元素自己自成一个集合
16+
for (var i = 0; i < size; i++) {
17+
parent![i] = i;
18+
rank![i] = 1;
19+
}
20+
}
21+
22+
@override
23+
int? getSize() {
24+
return parent!.length;
25+
}
26+
27+
// 查找过程, 查找元素p所对应的集合编号
28+
// O(h)复杂度, h为树的高度
29+
int find(int p) {
30+
if (p < 0 || p >= parent!.length) throw new Exception("p is out of bound.");
31+
32+
// 不断去查询自己的父亲节点, 直到到达根节点
33+
// 根节点的特点: parent[p] == p
34+
while (p != parent![p]) {
35+
p = parent![p];
36+
}
37+
return p;
38+
}
39+
40+
// 查看元素p和元素q是否所属一个集合
41+
// O(h)复杂度, h为树的高度
42+
@override
43+
bool isConnected(int p, int q) {
44+
return find(p) == find(q);
45+
}
46+
47+
// 合并元素p和元素q所属的集合
48+
// O(h)复杂度, h为树的高度
49+
@override
50+
unionElements(int p, int q) {
51+
int pRoot = find(p);
52+
int qRoot = find(q);
53+
54+
if (pRoot == qRoot) return;
55+
56+
// 根据两个元素所在树的rank不同判断合并方向
57+
// 将rank低的集合合并到rank高的集合上
58+
if (rank![pRoot] < rank![qRoot]) {
59+
parent![pRoot] = qRoot;
60+
} else if (rank![qRoot] < rank![pRoot]) {
61+
parent![qRoot] = pRoot;
62+
} else {
63+
// rank[pRoot] == rank[qRoot]
64+
parent![pRoot] = qRoot;
65+
rank![qRoot] += 1; // 此时, 我维护rank的值
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)