Java并查集链表实现

import java.util.LinkedList;
import java.util.List;

/**
 * 
 * @author energy1010
 *
 * @param <T>
 */
public class DisjointSet<T> {

	public List<HeadNode<T> > setList;
	public int size;
	
	public static class HeadNode<T>{
		public List<T> itemsList;
		public T val;
		public int num;
		public LinkNode<T> first;
		public LinkNode<T> tail;
		public HeadNode() {
			
		}
		public HeadNode(T val) {
			
			this.val = val;
			num+=1;
			if(itemsList==null){
				itemsList = new LinkedList<T>();
				itemsList.add(val);
				first = new LinkNode<T>(val, this);
				tail= first;
			}
		}
		
		public HeadNode(T[] val) {
			if(val.length>0){
				this.val = val[0];
				if(this.itemsList==null){
					this.itemsList = new LinkedList<T>();
					for(int i=0; i<val.length; i++){
						if(i==0){
							this.itemsList.add(val[i]);
							this.first = new LinkNode<T>(this.val, this);
							this.tail = first;
							this.num+=1;
						}else{
							addLinkNode(val[i]);
						}
					}
				}else{
					
				}
			}
		}
		
		
		public boolean contain(T val){
			if(itemsList!=null && itemsList.size()>0){
				return itemsList.contains(val);
			}
			return false;
		}
		
		public void addLinkNode(T val){
			if(itemsList==null){
				itemsList = new LinkedList<T>();
				first = new LinkNode<T>(val, this);
				tail= first;
			}else{
				LinkNode<T> newLinkNode  =  new LinkNode<T>(val, this);
				tail.next = newLinkNode;
				tail = newLinkNode;
			}
			itemsList.add(val);
			num+=1;
		}
		
		public void delLinkNode(T val){
			//TODO:
		}
		
		public void delHeadNode(){
			this.num =0 ;
			this.val = null;
			itemsList.clear();
			itemsList=null;
			first = null;
			tail = null;
		}
	
		public void printHeadNode(){
			System.out.printf("val: %s items:%s num:%s first:%s tail:%s
", val, itemsList, num, first.val, tail.val);
		}
		
		
//		@Override
//		public String toString() {
//			return String.format(", args)
////			return super.toString();
//		}
		
	}//HeadNode
	
	public boolean delHeadNode(HeadNode<T> headNode){
		if(this.setList!=null && this.setList.contains(headNode)){
			this.setList.remove(headNode);
			headNode.first.delLinkNode(headNode.first);
			headNode.delHeadNode();
			size-=1;
			return true;
		}else{
			return false;
		}
	}
	
	
	public static class LinkNode<T>{
		public HeadNode<T> headNode;
		public LinkNode<T> next;
		public T val;
		
		public LinkNode(T val, HeadNode<T> headNode){
			this.headNode = headNode;
			this.val= val;
		}
		
		public LinkNode<T> getTail(){
			LinkNode<T> tail  = this;
			while(tail.getTail()!=null){
				tail = tail.next;
			}
			return tail;
		}
		
		public void delLinkNode(LinkNode<T> linknode){
			linknode.headNode = null;
			linknode.val = null;
			while(linknode.next!=null){
				delLinkNode(linknode.next);
				linknode= linknode.next;
			}
		}
		
		@Override
		public String toString() {
			return String.format("val:%s head:%s", val, headNode.val );
//			return super.toString();
		}
		
	}//LinkNode
	
	public DisjointSet() {

	}
	
	
	public HeadNode<T> MakeSet(T val){
		HeadNode<T> newHeadNode = new HeadNode<T>(val);
		this.setList.add(newHeadNode);
		this.size+=1;
		return newHeadNode;
		
	}
	
	public HeadNode<T> MakeSet(T[] val){
		HeadNode<T> newHeadNode = null;
		if(val.length>0){
		newHeadNode = new HeadNode(val);
		this.setList.add(newHeadNode);
		this.size+=1;
		}
		return newHeadNode;
	}
	
	public HeadNode<T> FindSet(T val){
		if(setList!=null && size>0 && setList.size()>0 ){
			for(HeadNode<T> head : setList){
				if(head.contain(val)){
					return head;
				}
			}
		}
		return null;
	}
	
	public boolean isConnected(T a , T b){
		if(setList!=null ){
			for(HeadNode<T> h: setList){
				if(h.contain(a)&& h.contain(b)){
					return true;
				}
			}
//			return false;
		}
		return false;
	}

	public int contain(T a){
		int index = -1;
		boolean contain = false;
		if(setList!=null ){
			for(HeadNode<T> h: setList){
				index++;
				if(h.contain(a)){
					contain = true;
					break;
				}
			}
			if(!contain){
				index= -1;
			}
		}
		return index;
	}
	
	public HeadNode<T> add(T val){
		int index = contain(val);
		if( index ==-1){
			HeadNode<T> newHeadNode =  MakeSet(val);
			this.setList.add(newHeadNode);
			this.size++;
		}
		return this.setList.get(index);
	}
	
	public void UnionVal(T t1, T t2){
		System.out.printf("union val %s %s
", t1, t2);
		if(this.setList==null || this.size==0){
			this.setList = new LinkedList<DisjointSet.HeadNode<T>>();
			HeadNode<T> newHeadNode =MakeSet(t1);
			newHeadNode.addLinkNode(t2);
//			this.setList.add(newHeadNode);
//			this.size++;
		}else{
			int h1 = contain(t1);
			int h2  = contain(t2);
			if( h1==-1 && h2==-1){
				HeadNode<T> newHeadNode =MakeSet(t1);
				newHeadNode.addLinkNode(t2);
//				this.setList.add(newHeadNode);
//				this.size++;
			}else{
				if(h1!=-1 && h2!=-1){
					if(h1!=h2){
						UnionSet(this.setList.get(h1), this.setList.get(h2));
					}
				}else{
					if(h1!=-1){
						this.setList.get(h1).addLinkNode(t2);
					}else{
						this.setList.get(h2).addLinkNode(t1);
					}
				}
				
			}
		}
	}
	
	
	public void UnionSet(HeadNode<T> set1, HeadNode<T> set2) {
		if(set1!=null && set2!=null){
		int s1 = set1.num;
		int s2 = set2.num;
		if(s1<s2){
//			set2.itemsList.addAll(c)
			for(T t: set1.itemsList){
				if(!set2.itemsList.contains(t)){
					set2.addLinkNode(t);
				}
			}
			delHeadNode(set1);
			
		}else{
			for(T t: set2.itemsList){
				if(!set1.itemsList.contains(t)){
					set1.addLinkNode(t);
				}
			}
			delHeadNode(set2);
		}
		
		}else{
//			throw new Exception("UnionSet error");
		}
	}

	public void printDisJointSet(){
		if(setList==null){
			System.out.println("null disjointSet" );
			return;
		}
		System.out.printf("set size:%s %s
", size, setList.size() );
		for(HeadNode<T> h : setList){
			h.printHeadNode();
		}
	}
	
//	@Override
//	public String toString() {
//		return super.toString();
//	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		DisjointSet<String> disjointSet = new DisjointSet<String>();
		disjointSet.UnionVal("1", "2");
		disjointSet.printDisJointSet();
		
		disjointSet.UnionVal("3", "4");
		disjointSet.printDisJointSet();
		
		disjointSet.UnionVal("3", "6");
		disjointSet.printDisJointSet();
		
		disjointSet.UnionVal("1", "4");
		disjointSet.printDisJointSet();
		
		//		disjointSet.MakeSet(new String[]{"a", "b"});
//		disjointSet.add("a");
//		disjointSet.add("c");
	}

}
原文地址:https://www.cnblogs.com/energy1010/p/6438638.html