Skip to content

Commit 0d9a3a0

Browse files
committed
并查集size优化
1 parent 230cf4e commit 0d9a3a0

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

app/src/main/java/com/example/datastructure/UnionFind2.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
* 并查集2
55
* quick union
66
*
7-
* 内部结构是数组形成的树,孩子指向父亲节点
7+
* 内部结构是数组形成的多颗树,孩子指向父亲节点
8+
*
9+
* 这个版本的并查集有个问题,合并的时候都是按照p的根节点往q的根节点上连接,可能会导致p树越来越深
810
*/
911
public class UnionFind2 implements UnionFind {
1012
private int[] parent;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.example.datastructure;
2+
3+
/**
4+
* 对并查集2的优化版
5+
* 优化 size优化,节点个数少的树合并到节点个数多的树
6+
*/
7+
public class UnionFind3 implements UnionFind {
8+
private int[] parent;
9+
private int[] sz;
10+
11+
public UnionFind3(int size) {
12+
this.parent = new int[size];
13+
this.sz = new int[size];
14+
for (int i = 0; i < size; i++) {
15+
parent[i] = i;//初始化,每个元素独立都是一个根节点指向自己
16+
sz[i] = 1;
17+
}
18+
}
19+
20+
//p和q是否所属一个集合
21+
@Override
22+
public boolean isConnected(int p, int q) {
23+
return find(p) == find(q);
24+
}
25+
26+
@Override
27+
public int getSize() {
28+
return parent.length;
29+
}
30+
31+
//树的根节点连接
32+
@Override
33+
public void unionEle(int p, int q) {
34+
int pRoot = find(p);
35+
int qRoot = find(q);
36+
37+
if (pRoot == qRoot)
38+
return;
39+
40+
if (sz[pRoot] < sz[qRoot]) {//p节点少,p树指向q树根节点,q树节点增加
41+
parent[pRoot] = parent[qRoot];
42+
sz[qRoot] += sz[pRoot];
43+
} else {
44+
parent[qRoot] = parent[pRoot];
45+
sz[pRoot] += sz[qRoot];
46+
}
47+
}
48+
49+
/**
50+
* 查找根节点即遍历树深度
51+
* 初始每个元素的父亲节点都是自己,unionEle之后就会形成树型结构
52+
* 复杂度:O(h)
53+
*
54+
* @param p
55+
* @return
56+
*/
57+
private int find(int p) {
58+
if (p < 0 || p >= parent.length)
59+
throw new IllegalArgumentException("越界");
60+
61+
while (p != parent[p])
62+
p = parent[p];//遍历查找根节点
63+
64+
return p;
65+
}
66+
}

0 commit comments

Comments
 (0)