算法笔记练习 题解合集
题目
题目描述
判断两序列是否为同一二叉搜索树序列
输入
开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。
输出
如果序列相同则输出YES,否则输出NO
样例输入
6
45021
12045
54120
45021
45012
21054
50412
0
样例输出
NO
NO
YES
NO
NO
NO
思路
因为先序遍历结果和中序遍历结果能唯一确定一棵二叉树,所以先生成第一行的先序遍历结果和中序遍历结果,再对下面的每一行都如此做,若某行的先序遍历结果和中序遍历结果都和第一行的完全相同,则输出YES
,否则NO
。
为了防止内存泄漏,写了一个删除整棵二叉树的函数deleteTree
来释放空间,但是delete
和new
必须成对出现,导致代码比原先的稍微复杂了一点。(不写也可以,数据量小)
代码
#include <iostream>
#include <string>
using namespace std;
struct Node {
char data;
Node *lchild, *rchild;
};
Node* newNode(char x) {
Node *p = new Node;
p->data = x;
p->lchild = p->rchild = nullptr;
return p;
}
void insert(Node* &root, char x) {
if (!root) {
root = newNode(x);
return;
}
if (x <= root->data)
insert(root->lchild, x);
else if (x > root->data)
insert(root->rchild, x);
}
void preOrder(Node *root, string &pre) {
pre += root->data;
if (root->lchild)
preOrder(root->lchild, pre);
if (root->rchild)
preOrder(root->rchild, pre);
}
void inOrder(Node *root, string &in) {
if (root->lchild)
inOrder(root->lchild, in);
in += root->data;
if (root->rchild)
inOrder(root->rchild, in);
}
void deleteTree(Node* &root) {
if (root == nullptr)
return;
deleteTree(root->lchild);
deleteTree(root->rchild);
delete root;
}
int main() {
int n;
string input, pre1, in1, pre2, in2;
while (scanf("%d", &n) != EOF && n) {
getchar();
string pre1, in1, pre2, in2;
getline(cin, input);
Node *root1 = newNode(input[0]);
for (int i = 1; i < input.size(); ++i)
insert(root1, input[i]);
preOrder(root1, pre1);
inOrder(root1, in1);
for (int i = 0; i < n; ++i) {
getline(cin, input);
Node *root2 = newNode(input[0]);
for (int j = 1; j < input.size(); ++j)
insert(root2, input[j]);
pre2.clear();
in2.clear();
preOrder(root2, pre2);
inOrder(root2, in2);
puts(pre1 == pre2 && in1 == in2 ? "YES" : "NO");
deleteTree(root2);
}
deleteTree(root1);
}
return 0;
}