判断两棵树在不考虑子树顺序时是否相同
思路:采用递归的思想,先判断两棵树t1和t2的根结点的元素是否相同,再判断两棵树根结点的子树个数是否相等,最后通过多次递归调用本算法来判断:是否存在两棵树根结点的子树集之间的一个匹配(或一一对应),使得每一对子树相等。算法中用到了一个临时数组temp[]来存放两棵树根结点的子树的匹配信息,temp[i]=j表示t1的第i棵子树与t2的第j棵子树相匹配。
程序代码:
int equal(CSTree t1,CSTree t2)
{
PCSNode p1,p2;
int n1,n2,i;
int *temp;
if(t1 == NULL && t2 == NULL)
return 1;
if( (t1 == NULL && t2 != NULL) || (t1 != NULL && t2 == NULL) )
return 0;
if(t1->info != t2->info)
return 0;
for(p1 = t1->lchild,n1 = 0;p1 != NULL;p1 = p1->rsibling)
n1++; //计算t1根结点的子树个数
for(p2 = t2->lchild,n2 = 0;p2 != NULL;p2 = p2->rsibling)
n2++; //计算t2根结点的子树个数
if(n1 != n2)
return 0;
temp = (int *)malloc(n1*sizeof(int));
for(i = 0;i < n1;i++)
temp[i] = -1; //给temp数组赋初值
for(p1 = t1->lchild,n1 = 0;p1 != NULL;p1 = p1->rsibling)
{ //对应t1根结点的每一棵子树p1
for(p2 = t2->lchild,n2 = 0;p2 != NULL;p2 = p2->rsibling)
{ //对应t2根结点的每一棵子树p2
if(equal(p1,p2) == 1)
{
for(i = 0;i < n1;i++)
if(temp[i] == n2)
break; //虽然子树p1和p2相等,但p2在之前的匹配中出现过,故p1与p2不加入新的匹配
if(i == n1)
{
temp[n1] = n2; //虽然子树p1和p2相等,但p2在之前的匹配未出现过,故p1与p2加入新的匹配
break;
}
}
n2++;
}
if(p2 == NULL)
{
free(temp);
return 0; //不存在与p1相匹配的子树,因此t1与t2一定不相等
}
n1++;
}
free(temp);
return 1; //树t1与t2根结点的子树个数相等,且t1根结点的每棵子树匹配成功,故t1与t2相等
}