不相交集合的数据结构
来源:互联网 发布:2016淘宝分销刷信誉 编辑:程序博客网 时间:2024/05/17 09:06
不相交集合的数据结构
本来想着来实现基于贪婪思想的Kruskal算法—–最小生成树的算法之一。
却发现当我们合并集合时里面还涉及到一个判断“环”的问题,继而有了本篇博文:不相交集合的数据结构。
关于不相交集合的数据结构,这里作一个简单的介绍,更多的可看这里
- 第一:我们假设我们有n个不相交的集合{Si},i=1~n;其中每个集合中都有一个“代表元素”(这个“代表元素”你可以理解为我们班级中的“班长”,对外“班长”就代表了我们整个班级);
- 第二:不相交的集合的数据结构,要支持UNION(x,y)操作:将包含x和y的两个动态集合(Si和Sj)合并成一个新的集合,即完成两个集合的合并,然后为这个新的集合选取一个“代表元素”,虽然UNION的很多实现都是直接选取Si或者是Sj的“代表元素”继续作为合并后集合的“代表元素”,但是你也可以选择集合中的其他元素作为代表元素。
- 第三 、不相交的集合的数据结构,支持FIND-SET(x)操作:返回x所在集合的代表元素。
不相交集合数据结构有一些应用,例如:确定无向图的连通分量,以及图中是否有环。
下面我们用java来实现判断一个图中是否有环,判断是否有环的思想可以看这里
第一步:我们定义了一个边的类,如下
package org.wrh.algorithmdemo;//边的类public class Edge { /* * 边的始点 * */ private int src; /* * 边的终点 * */ private int dest; public Edge(int src, int dest) { super(); this.src = src; this.dest = dest; } public int getSrc() { return src; } public void setSrc(int src) { this.src = src; } public int getDest() { return dest; } public void setDest(int dest) { this.dest = dest; }}
第二步:我们定义的一个图的类,如下
package org.wrh.algorithmdemo;import java.util.List;//图的类public class Graph { /* * 图中的顶点的个数 * */ private int vertices_number; /* * 图中的边的个数 * */ private int edges_number; /* * 图中边对象的引用集合 * */ private List<Edge> edge; //下面为构造函数和属性的get、set方法 public Graph(int vertices_number, int edges_number) { super(); this.vertices_number = vertices_number; this.edges_number = edges_number; } public int getVertices_number() { return vertices_number; } public void setVertices_number(int vertices_number) { this.vertices_number = vertices_number; } public int getEdges_number() { return edges_number; } public void setEdges_number(int edges_number) { this.edges_number = edges_number; } public List<Edge> getEdge() { return edge; } public void setEdge(List<Edge> edge) { this.edge = edge; }}
第三步:主函数类,如下
package org.wrh.algorithmdemo;import java.util.ArrayList;import java.util.List;public class DisjuntSetCircle { public static void main(String[] args) { /* * 给定边的数量和顶点的数量 * */ int vertices_num=4; int edges_num=4; /* * new一个Graph对象, * */ Graph graph=new Graph(vertices_num,edges_num); /* * 新建edges_num个Edge对象,构造一个List对象 * */ List<Edge> edge=new ArrayList<Edge>(); edge.add(new Edge(0,1)); edge.add(new Edge(1,2)); edge.add(new Edge(2,3)); edge.add(new Edge(3,0)); /* * 将边加载到图中 * */ graph.setEdge(edge);//这样就构成了一个4个顶点4条边的图 /* *定义parent数组来记录每个顶点属于那个集合的"代表元素"; * 例如:我们的学生管理系统一般会记录我们的"班长"是谁一样 * * */ int parent []=new int[vertices_num]; /* * 首先我们将这些集合的代表元素初始化为 -1,表示他们都是单个元素的集合 * */ for(int i=0;i<parent.length;i++){ parent[i]=-1; } /* * 下面来判断这个图中是否有环 * */ if(isCycle(graph,parent)){ System.out.println("此图有环"); } else{ System.out.println("此图没有环"); } } private static boolean isCycle(Graph graph,int[] parent) { /* *获取边的数量 */ int num=graph.getEdge().size(); int src_represent;//用来表示边的起始点的"代表元素" int dest_represent;//用来表示边的终点的"代表元素" for(int i=0;i<num;i++){ int src=graph.getEdge().get(i).getSrc();//得到边的起始点 int dest=graph.getEdge().get(i).getDest();//得到边的终点 src_represent=find(parent,src);//得到起点所属集合的代表元素 dest_represent=find(parent,dest);//同上 if(src_represent==dest_represent){//说明,边的两个顶点已经出现在了集合中,加上此边之后,构成"环" return true; } else{//否则,合并 union(parent,src_represent,dest_represent); } } return false; } /* * 合并两个不相交的集合 * */ private static void union(int[] parent, int src, int dest) { /* * 由于两者是两个集合的不同的"代表元素",因此将其中的的“代表元素”改为另外一个即可完成合并 * */ parent[src]=dest; } /* * 用来寻找顶点X所在集合的"代表元素" * */ private static int find(int[] parent, int x) { /* * 首先判断顶点x的"代表元素是不是等于-1",若等于-1,则说明,其自身就是"代表元素"; * 若不等于-1,则说明此点在某个集合中并且不是代表元素,我们需找到他的代表元素的标号,即我们需要向上查找 * */ if(parent[x]==-1){ return x; } return find(parent,parent[x]); }}
上面的代码中注释写的比较详细,这里就不在解释,相信大家都能够看懂
总结
- 这篇博文是关于“环”的检测的思想还是挺简单的,主要是为我们后面最小生成树算法的java实现做准备的,关于最小生成树的java实现,我最近将会完成。
关于”环”的检测的C语言实现和不相交集合的数据结构的知识可看这里,在此,对geeksforgeeks表示感谢,在这里,我学习到了很多知识。
1 1
- 不相交集合的数据结构
- 用于不相交集合的数据结构
- 算法导论21(用于不相交集合的数据结构)
- 用于不相交集合的数据结构(并查集)
- 算法导论笔记:21用于不相交集合的数据结构
- 算法导论 第二十一章:不相交集合的数据结构
- 第21章:用于不相交集合的数据结构
- 算法导论之用于不相交集合的数据结构
- 第二十一章 用于不相交集合的数据结构
- 算法导论用于不相交集合的数据结构
- 不相交集合的数据结构-并查集
- 算法导论学习笔记-第二十一章-用于不相交集合的数据结构
- 算法导论代码 第21章 用于不相交集合的数据结构
- [算法导论读书笔记]用于不相交集合的数据结构(并查集)
- 算法导论学习笔记(15)——用于不相交集合的数据结构
- 算法导论 第21章 用于不相交集合的数据结构
- 并查集——用于不相交集合的数据结构
- 用于不相交集合的数据结构——查并集
- Android自定义控件
- iOS开发数据持久化技术02——plist介绍
- 高效位运算 __builtin_系列函数
- 我火狐浏览器的好多TMP的临时文件都跑桌面来了,怎么修改存放地方啊?
- 编译错误:undefined reference to `clock_gettime'
- 不相交集合的数据结构
- C++函数可变参数实现原理探究——以实现printf为例
- file_get_contents的深入
- BZOJ1257 [CQOI2007]余数之和sum(枚举商)
- Matlab图像处理系列3———空间域锐化滤波器
- 卫星照片
- C++中如何计算程序运行的时间
- HDU 1317 Bellman-Ford
- leetcode--Intersection of Two Linked Lists