/* 8-6 不相交集的类架构*/
class DisjSets
{
public:
explicit DisjSets( int numElements );
int find( int x ) const;
int find( int x );
void unionSets( int root1, int root2 );
private:
vector<int> s;
};
/*8-7 不相交集的初始化例程*/
/*construct the disjoint sets oobject. numElements is the initial number of disjoint sets.*/
DisjSets::DisjSets( int numElements ) : s(numElements )
{
for( int i=0;i<s.size();i++)
s[i] = -1;
}
/*8-8 union (不是最好的方法)*/
/*union two disjoint sets.For simplicity,we assume root1 and root2 are distinct and represent set names.
*root1 is the root of set 1
*root2 is the root of set 2.
*/
void DisjSets::unionSets( int root1,int root2 )
{
s[ root2 ] = root1;/*root2的父亲节点是root1*/
}
/*8-9 一个简单的不相交集find 算法*/
/* perform a find.Error checks omitted again for simplicity.Return the set containing x.*/
int DisjSets::find( int x ) const
{
if( s[x] <0)
return x;
else
return find( s[x] );
}
/*8-13 按高度(秩)求并的程序*/
/* union two disjoint sets. for simplicity,we assume root1 and root2 are distinct and reppresent set names*/
/*root1 is the root of set 1.root2 is the root of set 2.*/
void DisjSets::unionSets( int root1, int root2 )
{
if( s[root2] < s[ root1]) //root2 is deeper
s[root1] = root2; //make root2 new root
else
{
if( s[root1] == s[root2] )
s[ root1 ]--; //update height if same
s[ root2 ] root1; //make root1 new root
}
}
应用: 求并/查找数据结构的一个例子是迷宫的生成,可以把这个迷宫看成是有单元组成的m*n的矩形,在该矩形中左上角的单元被连通到右下角单元,而且这些单元与相邻单元用墙壁分隔开来。
算法:从各处的墙壁开始(除入口和出口之外)。此时,不断随机选择一面墙,如果被该墙分割的单元彼此不连通,那么就把这面墙拆掉。重复这个过程,直到开始单元和终止单元连通,那么就得到一个迷宫。实际上不断地拆掉墙壁直到每个单元都可以从其他单元达到更好(这会使迷宫产生更多误导的路径)。
数据结构之不相交集的应用例程
最新推荐文章于 2022-05-21 21:47:39 发布