• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
SilentSherlock
博客园    首页    新随笔    联系   管理    订阅  订阅
【数据结构】关于并查集的原理

并查集的定义和常用的地方

  并查集一般用在解决动态联通性的问题,可以用来检验给出的两个点是否属于同一个集合,也可以根据条件将两个点加入同一个集合,常见的算法问题有岛屿问题,判断网格点的联通性等。在oi-wiki上的解释更加详细,也简单易懂。

并查集的API

public class UnionFind 说明
UnionFind(int n) 构造函数,初始化一个含有n个量的数组
int find(int p) 找到p所属集合的标识符,中间可以使用路径压缩
void union(int p, int q) 将两个点所在集合进行合并
int count() 返回并查集中的集合数目
boolean isConnected(int p, int q) 检验两个点是否在同一个集合

 

 

 

 

 

 

 

 

重要函数的实现和说明

UnionFind(int n)

并查集中的私有属性一般有两个

1 private int[] record;//记录集合
2 private int count;//集合数目
View Code

构造函数写法

1 public UnionFind(int n) {
2         record = new int[n];
3         for (int i = 0;i < n;i++) {
4             record[i] = i;//初始化时每个点所在集合的标识符都是自己
5         }
6         count = n;
7 }

int find(int p)

根据构造函数可以知道record[i]代表i所在集合标识符,record[i] = i时代表集合链接达到顶点,类似于家族中的祖先。

1 //找到p所在集合的标识符
2 public int find(int p) {
3         if (record[p] != p) record[p] = find(record[p]);//只有当record[p] = p时才说明p找到了他所在集合的标识符,否则就进行路径压缩
4         return record[p];
5 }

void union(int p, int q)

合并两个点所在的集合,其实就是让其中一个集合的顶点链接到另一个集合的顶点。

1 //合并两个点所在集合
2 public void union(int p, int q) {
3         int pid = find(p);
4         int qid = find(q);
5         if (pid == qid) return;//p,q在同一个集合里
6         record[pid] = qid;//将p所在集合合并到q所在集合内,可以按秩合并
7         count--;//集合数减一
8 }

并查集的完整实现

 1 public class UnionFind {
 2 
 3     private int[] record;
 4     private int count;
 5 
 6     public UnionFind(int n) {
 7         record = new int[n];
 8         for (int i = 0;i < n;i++) {
 9             record[i] = i;//初始化时每个点所在集合的标识符都是自己
10         }
11         count = n;
12     }
13 
14     //找到p所在集合的标识符
15     public int find(int p) {
16         if (record[p] != p) record[p] = find(record[p]);//只有当record[p] = p时才说明p找到了他所在集合的标识符,否则就进行路径压缩
17         return record[p];
18     }
19 
20     //合并两个点所在集合
21     public void union(int p, int q) {
22         int pid = find(p);
23         int qid = find(q);
24         if (pid == qid) return;//p,q在同一个集合里
25         record[pid] = qid;//将p所在集合合并到q所在集合内,可以按秩合并
26         count--;//集合数减一
27     }
28 
29     public boolean isConnected(int p, int q) {
30         return find(p) == find(q);
31     }
32 
33     public int count() {
34         return count;
35     }
36 }

 

posted on 2020-09-11 12:34  SilentSherlock  阅读(298)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3