给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。
输入格式:
输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。
简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理。
输出格式:
对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。
输入样例:
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0
输出样例:
Yes
No
No
解题思路:
将所给的节点序列,建成树,然后判断两棵树是否一样
代码:
#include <iostream>
using namespace std;
using TreeNode = class Node*;
class Node {
public:
int data;
TreeNode Left;
TreeNode Right;
};
TreeNode buildTree(int Num_of_Node); //建树
TreeNode Insert(int data, TreeNode BT); //插入结点
bool Is_Same_BK_Tree(TreeNode T0, TreeNode T1); //判断是否是同一棵二叉搜索树
int main() {
int Num_of_Node; //树的结点数
int N; //需要判断的序列数
int count = 0; //用来记录需要判断
int result[100]; //用来记录结果
while (1) {
cin >> Num_of_Node;
if (Num_of_Node == 0) break; //如果是0就退出循环
cin >> N;
TreeNode T0 = buildTree(Num_of_Node); //接受输入建成树,返回头节点
for (int i = count; i < N + count; i++) {
TreeNode T1 = buildTree(Num_of_Node);
if (Is_Same_BK_Tree(T0, T1)) result[i+1]=1;
else result[i+1]=0;
}
count += N;
}
for (int i = 0; i < count; i++) { //输出最后的结果
if (result[i + 1] == 1) cout << "Yes";
else cout << "No";
if (i != count - 1) cout << endl;
}
return 0;
}
TreeNode buildTree(int Num_of_Node) {
TreeNode BT = nullptr;
int node;
for (int i = 0; i < Num_of_Node; i++) {
cin >> node;
BT = Insert(node, BT);
}
return BT;
}
TreeNode Insert(int data, TreeNode BT) {
if (!BT) { //如果树为空,就建一个节点
BT = new Node;
BT->data = data;
BT->Left = BT->Right = nullptr;
}
else if (data < BT->data) { //应插入左子树, 递归调用
BT->Left=Insert(data, BT->Left);
}
else if (data > BT->data) { //右子树递归
BT->Right=Insert(data, BT->Right);
}
return BT;
}
bool Is_Same_BK_Tree(TreeNode T0, TreeNode T1) {
if (T0 == nullptr && T1 == nullptr) return true; //如果两个结点都为空, 返回true
if ((T0 == nullptr && T1 != nullptr) || (T1 == nullptr && T0 != nullptr)) \
return false; //一个空一个不空, 返回false
if (T0->data != T1->data) return false; //两个根节点不同 ,返回false
if (T0->data == T1->data) return (Is_Same_BK_Tree(T0->Left, T1->Left) && \
Is_Same_BK_Tree(T0->Right, T1->Right)); //如果根节点相同,就递归的看左右子节点
}