算法:
并查集是一种树型的数据结构,用于处理一些不交集的合并及查询问题。解决动态联通性一类问题的一种算法。
有makeSet方法 : 设置单元素集合
Find: 确定元素属于哪一个子集。这个方法是不断的向上查找父亲节点,直到根节点为止。
Union: 将两个子集合并成同一个集合。
Union
下图Find(D)返回A,Find(F)返回A。
UNION(D,F)参数是两个集合的元素,找到他们的代表A,H然后让他们进行合并操作。
上图演示并查集的两个操作一个是Find,一个是Union.
代码:
public class UnionFind{
//不一定是树,链表,类不需要指针,指向另一个节点
public class Node{
//whatever you like
int val;
}
public class UnionFindSet{
public HashMap<Node,Node> fatherMap;
public HashMap<Node,Integer> siteMap;
public UnionFindSet(){
fatherMap = new HashMap<Node,Node>();
siteMap = new HashMap<Node,Integer>();
}
public void makeSet(List<Node> nodes){
fatherMap.clear();
siteMap.clear();
for(Node node : Nodes){
fatherMap.put(node,node); //单元数集合
siteMap.put(node,1); //集合元素个数
}
}
private Node findHead(Node node){
Node father = fatherMap.get(node);
if(father != node){ //找元素根节点
father = findHead(father);
}
//fatherMap.put(Node,father); //路径压缩,
return father;
}
public boolean isSameSet(Node a, Node b){
return findHead(a) == findHead(b);
}
public void union(Node a, Node b){
if(a== null || b== null){
return;
}
Node aHead = findHead(a);
Node bHead = findHead(b);
if(aHead != bHead){
int aSetSize = sizeMap.get(aHead);
int bSetSize = sizeMap.get(bHead);
if(aSetSize <= bSetSize){
fatherMap.put(aHead,bHead);
sizeMap.put(bHead,aSetSize+bSetSize);
}else {
fatherMap.put(bHead,aHead);
sizeMap.put(aHead,aSetSize+bSetSize);
}
}
}
}
public static void main(String[] args){
List<Node> nodes1 = new ArrayList<Code_04_UnionFind.Node>();
Node a = new UnionFind().new Node();
Node b = new UnionFind().new Node();
Node c = new UnionFind().new Node();
Node d = new UnionFind().new Node();
nodes1.add(a);
nodes1.add(b);
nodes1.add(c);
nodes1.add(d);
List<Node> nodes2 = new ArrayList<Code_04_UnionFind.Node>();
Node e = new UnionFind().new Node();
Node f = new UnionFind().new Node();
Node g = new UnionFind().new Node();
Node h = new UnionFind().new Node();
nodes2.add(e);
nodes2.add(f);
nodes2.add(g);
nodes2.add(h);
UnionFindSet unionfind = new UnionFind().new UnionFindSet();
unionfind.makeSets(nodes1);
unionfind.makeSets(nodes2);
//组建左边的集合
unionfind.union(c, a);
unionfind.union(b, c);
unionfind.union(d, c);
//组建右边的集合
unionfind.union(e, h);
unionfind.union(g, e);
unionfind.union(f, e);
//合并两个集合
unionfind.union(h,a);
}
}