树结构表示下集合的合并与元素的查找

/*  树结构表示下集合的合并与元素的查找(此程序在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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值