并查集

//UNION(x,y)是将x,y分属的集合合并成一个集合,集合名字为两个集合名称的其中一个(按秩合并)
//FIND(x)是寻找x所属的集合名称(路径压缩)
//其中的关键是要快速找到根节点(集合名称)
//使用条件:不需要考虑集合内部情况,只要快速知道集合名称(根节点),并以此判断
//具体用处:1.任意两个人是否有亲属关系;2.互不相通的集合数;3.网络连接判断;4.变量名等同性(类似于指针的概念)

//数据结构有两种
//1.数组表示法:下标j表示节点j,A[j]表示j的父节点,例如9的父节点是4,则有A[9]=4(数组型适用于连续元素)
//2.树表示法: 3个成员变量,rank表示该节点的秩,value表示该节点的值,father表示指向父节点的指针(普遍使用,如果是连续数据则数组表示法更好)



#include <iostream>
using namespace std;

#define N 50

//树表示法(至于数组表示法,则使用性不是很强,不写)
typedef struct NODE
{
	int rank;
	int value;
	NODE * father;
	NODE(int value):father(NULL){
		this->rank=0;
		this->value=value;
		//this->father =NULL;
	}
}Node;
void  union1(Node *a,Node *b);
Node*  find1(Node *a);
Node*  find2(Node *a);

void  union1(Node *a,Node *b){
	//``a,b为两个集合,比较两者的rank,相等则a指向b同时b的rank+1,不等则低的指向高的``
	//有问题,这里的a,b的定义不是两个集合的根节点,而是两个集合的任意两个节点,因此要先找到a,b所属的根节点,在进行合并操作
	//a,b所属的根节点
	Node *pa=find2(a);
	Node *pb=find2(b);
	if (pa->rank <= pb->rank)
	{
		pa->father=pb;
		if (pa->rank == pb->rank)
		{
			pb->rank++;
		}
	}
	else 
	{
		pb->father=pa;
	}
}

Node*  find1(Node *a){//返回a节点所属的根节点(同时压缩路径)
	Node *root=a;
	while(root->father!=NULL) {//寻找根节点,直到father为NULL
	    root =root->father;
	}
	//跳出循环,此时root指向的就是根节点
	//压缩路径,理由是只有先找到根节点,才能压缩路径
	while(a!=root) {//a此时为移动指针,root此时为根节点指针,如果不相等,则将a指向root,同时a指针指向father
		Node *temp=a;
		a=a->father;
		temp->father=root;
	}//可以在优化,理由是a遍历的时候,最后一次是多余的,可以省去
	//不可行,最后一次不是多余,如果find的节点本身就是根节点,则会产生错误,如下的注释,因此不可优化
	return root;
}

Node*  find2(Node *a){
	//代码清晰易懂
	Node *y=a;
	while(y->father!=NULL) {
	    y=y->father;
	}
	Node *root=y;
	y=a;
	while(y->father!=NULL) {//未考虑到当y本身就是root时,y->father为NULL,应该为y!=root或者y->father!=NULL
	    Node *temp=y->father;
	    y->father=root;
	    y=temp;
	}
	return root;
}

int main(){
	//初始化数据
	
	Node* p1=new Node(1);
	Node* p2=new Node(2);
	Node* p3=new Node(3);
	Node* p4=new Node(4);
	Node* p5=new Node(5);
	Node* p6=new Node(6);
	Node* p7=new Node(7);
	union1(p1,p2);
	union1(p2,p3);
	union1(p4,p5);
	union1(p1,p4);
	Node *root=find2(p1);

	system("pause");
	return 0;

}
posted @ 2016-08-24 09:11  jiangge3  阅读(99)  评论(0)    收藏  举报