判断是否是同一棵二叉搜索树。多组数据该怎么修改代码

铁锈_ 2015-11-22 07:09:45
原题
是否同一棵二叉搜索树
给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。



#include <stdio.h>
#include <stdlib.h>


typedef struct BSTNode* BinTree ;
struct BSTNode
{
int Data ;
struct BSTNode* Left ;
struct BSTNode* Right ;
} ;


BinTree Insert( int x , BinTree BST )
{
if( BST==NULL )
{
BST=(BinTree) malloc( sizeof(struct BSTNode) ) ;
BST->Data = x ;
BST->Left = NULL ;
BST->Right = NULL ;
}
else
{
if( x<BST->Data )
BST->Left=Insert( x , BST->Left ) ;
else //二叉树元素不重复,不含相等的情况
BST->Right = Insert(x , BST->Right ) ;
}

return BST ;
}


BinTree Build( int N )//改二叉搜索树不含重复序列
{
BinTree Insert( int x , BinTree BST ) ;
int i , x ;
BinTree BST ;

BST = NULL ;
for(i=0 ; i<N ; i++)
{
scanf("%d",&x);
BST=Insert( x , BST ) ;
}
return BST ;
}

int SameBST( BinTree OrangeBST , BinTree BST )
{
if(BST==NULL&&OrangeBST==NULL)//两边都为空
return 1 ;
if( BST->Data != OrangeBST->Data )//根节点数据不同
return 0 ;
if( (BST->Left==NULL&&OrangeBST->Left!=NULL) || (BST->Left!=NULL&&OrangeBST->Left==NULL) )//一边左子树为空另一棵左子树非空
return 0 ;
if( BST->Left!=NULL && OrangeBST->Left!=NULL && BST->Left->Data!=OrangeBST->Left->Data)//两边左子树非空但元素不同
return 0 ;
if( BST->Left!=NULL&&OrangeBST->Left!=NULL && BST->Left->Data == OrangeBST->Left->Data)//两边左子树都非空并且元素相同,判断右子树
return SameBST( OrangeBST->Right , BST->Right ) ;

}


void InOrderTraversal( BinTree BST )
{
if(BST)
{
InOrderTraversal( BST->Left ) ;
printf("%d ",BST->Data ) ;
InOrderTraversal( BST->Right ) ;
}
}


int main()
{
int i ;
int N,L ; //每个序列插入元素的个数N , 需要检查的序列个数L
BinTree OrangeBST ;
// BinTree BST1,BST2 ;//不知道有几个待测量搜索树,定义变量个数未知,指针数组
BinTree NeedCompareBST[10] ;

while(1)
{
scanf("%d",&N) ;
if(N!=0)
{
scanf("%d",&L) ;
OrangeBST = Build( N ) ; //InOrderTraversal( OrangeBST ) ; printf("\n");
for(i=0 ; i<L ; i++ )
{
NeedCompareBST[i] = Build( N ) ;
//InOrderTraversal( NeedCompareBST[i] ) ; printf("\n");
}
for(i=0 ; i<L ; i++)
{
if( SameBST( OrangeBST , NeedCompareBST[i] ) )
printf("Yes\n") ;
else
printf("No\n");
}
}
else return 0 ;
}

}


...全文
254 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
铁锈_ 2015-11-23
  • 打赏
  • 举报
回复
return SameBST( OrangeBST->Right , BST->Right ) ;这句错了
lm_whales 2015-11-23
  • 打赏
  • 举报
回复
为何没有销毁树的代码 每组中,每个序列,只需要和第一个比较就好了,因为生成的二叉树必须是全同的 因此,只需要初始序列,和比较序列两个序列,就够用了 具体做法是 读取N,L 生成初始序列 first, 接着循环生成 比较序列 next 如果相同,销毁 next 重建序列 否则,输出结论"No" 这样就处理好一组数据了 此时销毁 这两个二叉树。 输出结论。“Yes” 另外也可以用数组表示二叉树这样就不需要销毁了 注意N<=10 每个序列,可以用最多十个节点表示。
铁锈_ 2015-11-23
  • 打赏
  • 举报
回复
引用 4 楼 lm_whales 的回复:
return SameBST( OrangeBST->Right , BST->Right ) ;
这句错了 这个判断实际上是不对的,没有找到确切位置, 确切位置是
if( BST->Data != OrangeBST->Data )//根节点数据不同 
        return 0 ;
因为
 if(BST==NULL&&OrangeBST==NULL)//两边都为空
        return 1 ;
    if( BST->Data != OrangeBST->Data )//根节点数据不同
        return 0 ;
这个判断,不能保证,在二者有一个为空的时候,不出错。 后面那种判断,
 if( (BST->Left==NULL&&OrangeBST->Left!=NULL) || (BST->Left!=NULL&&OrangeBST->Left==NULL) )//一边左子树为空另一棵左子树非空
        return 0 ;
    if( BST->Left!=NULL && OrangeBST->Left!=NULL && BST->Left->Data!=OrangeBST->Left->Data)//两边左子树非空但元素不同
        return 0 ;
    if(  BST->Left!=NULL&&OrangeBST->Left!=NULL && BST->Left->Data == OrangeBST->Left->Data)//两边左子树都非空并且元素相同,判断右子树
        return SameBST( OrangeBST->Right , BST->Right  ) ;
1是太复杂而没有必要, 2是很难找出错误,条件太多了, 代码应该力求简洁 这样才比较容易判断哪里出错。 对于比较复杂的表达式,最好分开几行写。 当然,更好的是,代码里不出现这种复杂的表达式。 C,C++ 语言,并不要求 所有 代码写在一行上, 所以一行最好只写功能单一的代码 条件表达式太复杂,应该分行写。 任何表达式过于复杂,都应该分行写,以便调试的时候,比较容易定位错误。
恩恩,记住了。你的方法使代码简洁不少呢
lm_whales 2015-11-23
  • 打赏
  • 举报
回复
return SameBST( OrangeBST->Right , BST->Right ) ;
这句错了 这个判断实际上是不对的,没有找到确切位置, 确切位置是
if( BST->Data != OrangeBST->Data )//根节点数据不同 
        return 0 ;
因为
 if(BST==NULL&&OrangeBST==NULL)//两边都为空
        return 1 ;
    if( BST->Data != OrangeBST->Data )//根节点数据不同
        return 0 ;
这个判断,不能保证,在二者有一个为空的时候,不出错。 后面那种判断,
 if( (BST->Left==NULL&&OrangeBST->Left!=NULL) || (BST->Left!=NULL&&OrangeBST->Left==NULL) )//一边左子树为空另一棵左子树非空
        return 0 ;
    if( BST->Left!=NULL && OrangeBST->Left!=NULL && BST->Left->Data!=OrangeBST->Left->Data)//两边左子树非空但元素不同
        return 0 ;
    if(  BST->Left!=NULL&&OrangeBST->Left!=NULL && BST->Left->Data == OrangeBST->Left->Data)//两边左子树都非空并且元素相同,判断右子树
        return SameBST( OrangeBST->Right , BST->Right  ) ;
1是太复杂而没有必要, 2是很难找出错误,条件太多了, 代码应该力求简洁 这样才比较容易判断哪里出错。 对于比较复杂的表达式,最好分开几行写。 当然,更好的是,代码里不出现这种复杂的表达式。 C,C++ 语言,并不要求 所有 代码写在一行上, 所以一行最好只写功能单一的代码 条件表达式太复杂,应该分行写。 任何表达式过于复杂,都应该分行写,以便调试的时候,比较容易定位错误。
lm_whales 2015-11-23
  • 打赏
  • 举报
回复

int SameBST( BinTree OrangeBST , BinTree BST )
{
    ///根节点相等判断 1 同为空节点,返回 1
    if(BST==NULL  && OrangeBST==NULL)//两边都为空
                return 1 ;
    if(BST==NULL)return 0; ///只有一个空节点,比较序列为空,返回 0
    if  (OrangeBST==NULL)return 0; 只有一个空节点,原始序列为空,返回 0
    
    if( BST->Data != OrangeBST->Data )//根节点数据不同 
        return 0 ;

    return SameBST( OrangeBST->Left , BST->Left  )
             && SameBST( OrangeBST->Right , BST->Right  );
}
这样就可以了,左右子树不必另外处理,各用一个递归调用足矣。

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧