算法起步之并查集(不相交集合数据结构)

简介: 原文: 算法起步之并查集(不相交集合数据结构)          在java中经典的数据结构基本都给实现好了,我们可以直接调用,但是并查集这种数据结构却没有很好的替代工具,在这里我们我们自己去实现并查集数据结构。
原文: 算法起步之并查集(不相交集合数据结构)

         在java中经典的数据结构基本都给实现好了,我们可以直接调用,但是并查集这种数据结构却没有很好的替代工具,在这里我们我们自己去实现并查集数据结构。首先我们先要去了解什么是并查集。并查集也是一种非常经典常用的数据结构。像求连通子图跟我们下面要研究的最小生成树问题都会用到并查集。并查集就是能够实现若干个不相交集合,较快的合并和判断元素所在集合的操作。不相交集合:一个不相交集合维护了一个不相交动态集合{s1,s2,s3……}我们用一个代表标示每一个集合,他是这个集合的成员。我们不关心哪个成员作为代表,仅关心2次查询这个集合时放回结果应该相同(如果我们不修改集合)。

    并查集主要就有三个方法:

    make-set(x)建立一个新集合唯一元素就是x,因为是不相交集合所以x不会出现在其他集合中。

    union(x,y)将包含x和y的2个动态集合合并成一个新集合。

    find-set(x)返回一个指针,这个指针指向包含x的集合的代表。

    这样说是不是有点懵,我们来看一个图。


       

        上图两棵树就是一个不相交集合,a数的代表就是a而e树代表就是e我们在a树上查找b则返回a而查找c也返回a说明b与c在同一结合上,而查找f返回e,说明b与e是在两个结合上,他们两个是不相交的。而union操作就是将两颗树合并成一棵树。

     我们先给出一个一般的实现,数组表示不相交集合保存的各个集合的元素。初始化时:


           每个元素都指向自己的父节点也就是自己。这种方式每个节点都指向自己的上一节点。而只有代表节点指向的是自己。所以我们根据这个来搜索代表节点。

public class Ufsarry {

	
	private int[] node;
	private int max;
	public void makeset(int n){
		node=new int[n+1];
		max=n;
		//所有的节点都是不相交集合,代表节点都指向自己。
		for (int i = 0; i < node.length; i++) {
			node[i]=i;
		}
	}
	public int findset(int x){
		while (x!=node[x]) {
			x=node[x];
		}
		return x;
	}
	public void union(int x,int y){
		node[x]=y;
	}
}
           下面我们要说的就是并查集的优化,按秩合并与路径压缩。听着好像很高深,其实很哄人的。两张图就可以解释。



            第一张图就是路径压缩,我们之前都是指向的上一节点,而压缩则是直接指向代表节点。而按秩合并则是我们外加一个属性来记录集合的秩。而秩多的则说明树比较高,我们将矮的树嫁接在高的树上,这样总的高度较小。而如果高度相同,则只需要将一个树嫁接过去,给他的秩加一即可。

public class Ufs {
	
	private int[] father;
	private int[] rank;
	
	public void makeset(int x){
		father[x]=x;
		rank[x]=0;
	}
	public int findset(int x){
		if (father[x]!=x) {
			father[x]=findset(father[x]);
		}
		return father[x];
	}
	
	public void union(int x,int y){
		x=findset(x);
		y=findset(y);
		if (x==y) {
			return;
		}else {
			if (rank[x]>rank[y]) {
				father[y]=x;
			}else{
				if (rank[x]==rank[y]) {
					rank[y]++;
				}
				father[x]=y;
			}
		}
	}


}


        优化后的代码并不比之前的代码复杂。我们这里是用的数组来实现的,当然也可以用链表来实现。我们下面要说的Kruskal算法的效率就要看,我们写的并查集的实现。而按秩合并与路径压缩是目前已知渐进时间最快的Kruskal算法实现方式。

友情提示:转载请注明出处【作者idlear    博客http://blog.csdn.net/idlear/article/details/19556587】


目录
相关文章
|
18天前
|
存储 算法 索引
【算法与数据结构】队列的实现详解
【算法与数据结构】队列的实现详解
|
22天前
|
算法
【算法与数据结构】二叉树(前中后)序遍历2
【算法与数据结构】二叉树(前中后)序遍历
|
10天前
|
存储 机器学习/深度学习 算法
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
19 1
|
18天前
|
算法 索引
【算法与数据结构】深入二叉树实现超详解(全源码优化)
【算法与数据结构】深入二叉树实现超详解(全源码优化)
|
18天前
|
存储 算法
【算法与数据结构】深入解析二叉树(二)之堆结构实现
【算法与数据结构】深入解析二叉树(二)之堆结构实现
|
22天前
|
算法 C语言
【算法与数据结构】 C语言实现单链表队列详解2
【算法与数据结构】 C语言实现单链表队列详解
|
22天前
|
存储 算法 C语言
【算法与数据结构】 C语言实现单链表队列详解1
【算法与数据结构】 C语言实现单链表队列详解
|
22天前
|
存储 缓存 算法
【算法与数据结构】栈的实现详解
【算法与数据结构】栈的实现详解
|
22天前
|
存储 算法 编译器
【数据结构】栈算法(算法原理+源码)
【数据结构】栈算法(算法原理+源码)
【数据结构】栈算法(算法原理+源码)
|
26天前
|
存储 算法 搜索推荐
【数据结构】排序算法
【数据结构】排序算法
27 3