69,382
社区成员
发帖
与我相关
我的任务
分享
#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 ;
}
}
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++ 语言,并不要求 所有 代码写在一行上,
所以一行最好只写功能单一的代码
条件表达式太复杂,应该分行写。
任何表达式过于复杂,都应该分行写,以便调试的时候,比较容易定位错误。
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 );
}
这样就可以了,左右子树不必另外处理,各用一个递归调用足矣。