/* 树结构表示下集合的合并与元素的查找(此程序在WIN-TC1.9.1版下调试通过)*/
#include "stdio.h"
#include "conio.h"
typedef struct
{
int data;
int tag; /*根节点为负的整数,表示该集合的基数的负值,否则为父节点索引指针 */
}NODE,*set;
set s1[1],s2[1]; /*定义二个集合,初始化每集合中元素个数为1*/
void Initset(set *s)
{
int i,m;
printf("输入集合中元素的个数:");
scanf("%d",&m); /*重新定义每个集合中元素的个数*/
s[m]=(set)malloc(m*sizeof(NODE));
for(i=1;i<=m;i++)
{
if(i==1)
s[i]->tag=-m;
else
s[i]->tag=s[i-1]->data;
printf("输入第 %d 个元素:",i);
scanf("%d",&s[i]->data);
}
}
void printset(set *s) /*输出集合中的元素*/
{ int i;
printf("输出集合中的元素:/n");
for(i=1;i<=-(s[1]->tag);i++)
printf("%d/t%d/n",s[i]->data,s[i]->tag);
}
int Find(set *s, int e)
{
int i,p,q,k;
k=s[e]->tag;
for(i=1;i<=-(s[1]->tag);i++)
{
if(s[i]->data==e)
{ p=s[i]->tag;
while(p>0) p=s[p]->tag;
while(k!=p)
{
q=s[k]->tag;
s[k]->tag=p;
k=q;
}
printf("查找成功!/n");
for(i=1;i<=-(s[1]->tag);i++) /*输出使用压缩规则后集合中的变化*/
printf("%d/t%d/n",s[i]->data,s[i]->tag);
return p;
}
}
printf("元素不在该集合中!/n"); /*查找不成功*/
return -1;
}
int Union(int e1,int e2)
{ int i,j,sum;
sum=s1[1]->tag+s2[1]->tag;
/*表示在s1中找到了e1和在s2中找到了e2 或在s1中找到了e2和在s2中找到了e1*/
if(Find(&s1,e1)!=-1 && Find(&s2,e2)!=-1 || Find(&s1,e2)!=-1 && Find(&s2,e1)!=-1)
{
if(s1[1]->tag>s2[1]->tag) /*元素少的集合合并到元素多的集合中并输出*/
{s1[1]->tag=s2[1]->tag; s2[1]->tag=sum; printset(&s1); }
else
{s2[1]->tag=s1[1]->tag; s1[1]->tag=sum; printset(&s2); }
return sum;
}
printf("两个集合中不存在 %d 或%d /n",e1,e2);
return -1;
}
main()
{
int i,d,index,elem1,elem2;
Initset(&s1); /*构造两个集合并输出*/
printset(&s1);
Initset(&s2);
printset(&s2);
printf("输入要查找的元素:/n");
scanf("%d",&d);
Find(&s1,d);
if(Find(&s1,d)!=-1)
printf("该元素位于第一个集合!/n");
if(Find(&s2,d)!=-1)
printf("该元素位于第二个集合!/n");
printf("分别输入两个集合中的一个元素:/n");
scanf("%d%d",&elem1,&elem2);
index=Union(elem1,elem2);
printf("合并后的根结点索引值为:%d/n",index);
getch();
}