PTA 7-4 是否同一棵二叉搜索树 思路分析及代码解析 v1.0
一、前导
1. 需要掌握的知识
二叉搜索树基本概念、建树
2. 题目信息
题目来源:PTA / 拼题A
题目地址:https://pintia.cn/problem-sets/15/problems/712
二、解题思路分析
1. 题意理解
- 输入数据
4 2 \\4表示树的节点个数,2表示待检查的序列个数
3 1 4 2 \\初始序列,待检查的序列以此为标准
3 4 1 2 \\待检查的序列
3 2 4 1 \\待检查的序列
2 1 \\同 4 2
2 1
1 2
0 \\0表示程序结束
- 输出数据
Yes \\对应待检查序列的检测结果
No
No
- 题意
不同的输入序列可能生成相同的二叉搜索树,若序列产生的二叉搜索树相同,输出Yes,否则输出No
2. 思路分析(重点)
- 根据二叉搜索树的特点,先建树再比对
三、具体实现
1. 弯路和bug
- 由于粗心、编码能力不强,导致犯了各种中二晚期错误。比如:在for()语句后面加了**;** 导致建树一直异常
2. 代码框架(重点)
2.1 采用的数据结构
使用结构体数组,命名时做到见名知意
typedef struct BinarySearchTree *PBST;
struct BinarySearchTree
{
int value;
PBST left;
PBST right;
};
2.2 程序主体框架
程序伪码描述
int main()
{
1.根据序列创建树
2.比较树
}
2.3 各分支函数
- PBST Add(PBST Tree,int input_value); 将节点加入树中,被CreateTree()调用。分为树空 和 树非空;树非空时,按搜索树左小右大的原则进行判定。属于建树基本功,需要熟练。
PBST Add(PBST Tree,int input_value)
{
if(!Tree)
{
Tree=(PBST)malloc(sizeof(struct BinarySearchTree));
Tree->value=input_value;
Tree->left=NULL;
Tree->right=NULL;
}
else
{
if( input_value < Tree->value)
Tree->left=Add(Tree->left,input_value);
else
Tree->right=Add(Tree->right,input_value);
}
return Tree;
}
- PBST CreateTree(PBST Tree,int TreeNode); 通过Add()完成建树
PBST CreateTree(PBST Tree,int TreeNode)
{
int input_value;
for(int j=0;j<TreeNode;j++)
{
cin>>input_value;
Tree=Add(Tree,input_value);
}
return Tree;
}
- bool Judge(PBST Tree1,PBST Tree2); 判定是否同一棵二叉搜索树,将所有场景考虑到就可以AC,此处锻炼自己逻辑思维能力
bool Judge(PBST T1,PBST T2)
{
if(!T1 && !T2) return true; //1.树都为空
if( (!T1 && T2) || (T1 && !T2) ) return false; //2.树一棵空,一棵不空
if(T1->value != T2->value) return false; //3.树根不同
else //4.树根相同,仅需要判定左子树,右子树用递归解决
{
if(!T1->left && !T2->left) return Judge(T1->right,T2->right);//4.1左子树均为空,递归右子树
if( (!T1->left && T2->left) || (T1->left && !T2->left) ) return false; //4.2 左子树一棵空 一棵不空
if(T1->left&&T2->left) return (Judge(T1->left,T2->left) && Judge(T1->right,T2->right)); //4.3 左子树不空,递归左右子树
}
}
3. 完整编码
#include <cstdlib>
#include <iostream>
using namespace std;
typedef struct BinarySearchTree *PBST;
struct BinarySearchTree
{
int value;
PBST left;
PBST right;
};
PBST Add(PBST Tree,int input_value);
PBST CreateTree(PBST Tree,int TreeNode);
bool Judge(PBST Tree1,PBST Tree2);
int main()
{
int TreeNode,CheckNumber;
bool result=false;
PBST ReferTree=NULL,CompareTree=NULL;
cin>>TreeNode>>CheckNumber;
while(true)
{
ReferTree=CreateTree(ReferTree,TreeNode);
while(CheckNumber)
{
CompareTree=CreateTree(CompareTree,TreeNode);
CheckNumber--;
result=Judge(ReferTree,CompareTree);
if(result) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
CompareTree=NULL;
result=false;
}
cin>>TreeNode;
if(!TreeNode) return 0;
cin>>CheckNumber;
ReferTree=NULL;
}
return 0;
}
PBST CreateTree(PBST Tree,int TreeNode)
{
int input_value;
for(int j=0;j<TreeNode;j++)
{
cin>>input_value;
Tree=Add(Tree,input_value);
}
return Tree;
}
PBST Add(PBST Tree,int input_value)
{
if(!Tree)
{
Tree=(PBST)malloc(sizeof(struct BinarySearchTree));
Tree->value=input_value;
Tree->left=NULL;
Tree->right=NULL;
}
else
{
if( input_value < Tree->value)
Tree->left=Add(Tree->left,input_value);
else
Tree->right=Add(Tree->right,input_value);
}
return Tree;
}
bool Judge(PBST T1,PBST T2)
{
if(!T1 && !T2) return true;
if( (!T1 && T2) || (T1 && !T2) ) return false;
if(T1->value != T2->value) return false;
else //root is same,judge the left
{
if(!T1->left && !T2->left) return Judge(T1->right,T2->right);
if( (!T1->left && T2->left) || (T1->left && !T2->left) ) return false;
if(T1->left&&T2->left) return (Judge(T1->left,T2->left) && Judge(T1->right,T2->right));
}
}
2021.10.8
进步点:考虑了内存的释放 + 代码整体规划
缺点:忘记了复位参考树,Debug了好久 哭死…
#include <iostream>
using namespace std;
typedef struct Node* BST;
typedef int ElementType;
struct Node
{
ElementType Value;
BST Left;
BST Right;
};
BST Insert(BST Tree, ElementType Value);
bool Judge(BST Tree01, BST Tree02);
void FreeMem(BST Tree);
int main()
{
int N; cin >> N;
while (N)
{
int M; cin >> M;
BST Tree01 = NULL;//fix bug
int Value;
for (int i = 0; i < N; i++)
{
cin >> Value;
Tree01 = Insert(Tree01, Value);
}
BST Tree02;
while (M--)
{
Tree02 = NULL;
for (int i = 0; i < N; i++)
{
cin >> Value;
Tree02 = Insert(Tree02, Value);
}
bool Result = Judge(Tree01, Tree02);
if (Result)
cout << "Yes" << endl;
else
cout << "No" << endl;
FreeMem(Tree02);
}
FreeMem(Tree01);
cin >> N;
}
return 0;
}
void FreeMem(BST Tree)
{
BST Left, Right;
if (!Tree)
return;
if (Tree)
{
Left = Tree->Left;
Right = Tree->Right;
delete Tree;
FreeMem(Left);
FreeMem(Right);
}
return;
}
bool Judge(BST Tree01, BST Tree02)
{
if (!Tree01 && !Tree02) //1.All Empty
return true;
if ((Tree01 && !Tree02) || (!Tree01 && Tree02)) //2. One Empty,the out
return false;
if (Tree01->Value != Tree02->Value)
return false;
else
return Judge(Tree01->Left,Tree02->Left) && Judge(Tree01->Right,Tree02->Right);
}
BST Insert(BST Tree, ElementType Value)
{
if (!Tree)
{
Tree = new struct Node;
Tree->Value = Value;
Tree->Left = Tree->Right = NULL;
}
else
{
if (Value > Tree->Value)
Tree->Right = Insert(Tree->Right, Value);
else
Tree->Left = Insert(Tree->Left, Value);
}
return Tree;
}