定义结构体
typedef int ElementType ;
typedef int parentType;
struct GNode{
ElementType data;
parentType parent;
};
typedef struct GNode setType[Max];
1、查找元素属于哪个集合
先找到元素x的存储位置->再找x的父亲,一层一层往上找父亲
/*作用:查找元素
传入参数:查找的元素x,已经建立起来的双亲表示法的树s[]*/
ElementType find(ElementType x,setType s[]){
int i;
//查找位置
for(i=0;i<Max && s[i]->data!=x;i++);
if(i>=Max) return -1;//查找失败
//找根节点
for(;s[i]->parent>=0;i=s[i]->parent);
return i;
}
2、把两个集合并起来
先把两个元素的根节点找到,再把其中一个根节点的父亲指向另一个根节点的数组下标
/*作用:将两个集合合并*/
void Union(ElementType x,ElementType y,setType s[]){
ElementType root1,root2;
root1=find(x,s);
root2=find(y,s);
s[root1]->parent=root2;
}
但是我们能够想象,当无数多个树一直合并合并,会导致树越来越高,查找根节点很费时,所以我们尽量把比较小的连接到表较大的(可能合并后高度改变不大),而且没有必要开辟空间,判断每个节点它是多高,因为我们只关心根节点到底有几个元素
所以可以利用根节点的parent,因为-1这个位置还可以刻画信息,这样的话,-1要改成这个集合有多少个元素。代码修改成
/*作用:将两个集合合并*/
void Union(ElementType x,ElementType y,setType s[]){
ElementType root1,root2;
root1=find(x,s);
root2=find(y,s);
//集合2比较大,这里是负数比较
if(s[root1]->parent >= s[root2]->parent){
s[root2]->parent+=s[root1]->parent;//更新集合数量
s[root1]->parent=root2;
}else{//集合1大
s[root1]->parent+=s[root2]->parent;//更新集合数量
s[root2]->parent=root1;
}
}