Data structure review - union search

Union search is a simple set representation that supports the following three operations:

(1) initialization;

(2) Merge disjoint sets;

(3) Find the sub-set where x is located in the set s and return the root node of the sub-set;

1. Initialization of union search

#define SIZE 100
int UFSets[SIZE];

//并查集的初始化
void initial(int s[])
{
	for(int i=0;i<SIZE;i++)
	{
		s[i]=-1;
	}
 } 

2. The find operation of the union search

 //并查集的“查”操作(函数在并查集s中查找并返回包含元素x的树的根)
 int find(int s[],int x)
 {
 	while(s[x]>=0)
 	x=s[x];
 	return x;     //根的s[]小于0 
  } 

3. Unoptimized Union operation for union search

  //并查集的"并"操作(函数求两个不相交子集合的并集)
  void Union(int s[],int root1,int root2)
  {
  	if(root1==root2)  //同一集合没必要合并 
  	return ;
  	s[root2]=root1;   //将根root2连接到根root1下面 
   } 

Since the union search is not optimized, after analysis, the worst time complexity of the algorithm is related to the tree height, which is O(n);

4. Optimization of union search

//优化后的Union,让小树合并到大树下面,确保树的高度不会增加
//此时根结点的数组中存放的是该棵树的总结点树的相反数 (即负数) 
void Union(int s[],int root1,int root2)
{
	if(root1==root2)
	return ;
	if(s[root1]<s[root2])  //说明根root1的结点比较多,是棵大树,需要把root2合并到root1 
	{
		s[root1]+=s[root2];    //大树的结点总数增加 
		s[root2]=root1;        //更改小树的根节点 
	}
	else
	{
		s[root2]+=s[root1];
		s[root1]=root2; 
	}
 } 

Optimize the union search and try not to make the tree "thin and tall", so choose to merge the small tree under the big tree, and store the opposite number of the summary point tree of the tree in the array corresponding to the root node. At this time, using mathematical induction, it can be known that the height of the tree <=logn+1; the time complexity is O(logn). 

5. The ultimate optimization of union search 

Optimize the find operation, find the root node first, and then hang all the nodes under the search path under the root node.

int find(int s[],int x)
{
	int root=x;
	while(s[root]>=0)    //找到根节点 
	{
		root=s[root];
	}
	while(x!=root)   //压缩路径,将查找路径上的所有结点都挂到根节点下 
	{
		int t=s[x];   //保存x的父节点 
		s[x]=root;    //修改x的父节点使其指向根节点 
		x=t;          //继续往上修改结点 
	}
	return root;       //返回根节点编号 
} 

The time complexity of find is O(a(n)). 

Guess you like

Origin blog.csdn.net/m0_51769031/article/details/125252321