题目描述
二叉树分别以数组存储方式创建、以先序遍历序列创建。输入二叉树的数组存储、先序遍历结果,判断根据它们创建的二叉树是否是同一棵二叉树。
输入
测试次数t
每组测试数据两行:
第一行:二叉树的数组存储(英文字母表示树结点,#表示空树)
第二行:二叉树的先序遍历结果(英文字母表示树结点,#表示空树)
输出
对每组测试数据,如果两种方式创建的是同一棵二叉树,输出YES,否则,输出NO。
输入样例1
3
ABCDE
ABD##E##C##
ABC##DE####W##F
AB##CDW###E#F##
abc##d
ab##c#d##
输出样例1
YES
YES
NO
NOTICE:我一开始的想法是根据先序遍历创建完二叉树后,层次遍历这棵二叉树,如果得到的遍历结果根输入中的数组存储结果相同的话,则说明是同一棵树,但是最后发现给的样例的第三组没过,自己在纸上写了一下,才发现这种算法有漏洞;
回到正题,这个题首先要搞懂数组存储的顺序是啥,其实就是从上往下,从左往右的顺序;这个题需要在先序创建二叉树时,将本来视为空的#字符,也创建一个结点将他放到二叉树中;之后对二叉树进行层次遍历,将遍历到的每个字符与数组存储结果字符串的每个字符逐个进行比较。
#include <iostream>
#include <string>
#include <queue>
using namespace std;
class BiTreeNode
{
public:
char data;
BiTreeNode* lchild;
BiTreeNode* rchild;
BiTreeNode():data(' '),lchild(nullptr),rchild(nullptr){}
~BiTreeNode(){}
};
class BiTree
{
private:
BiTreeNode* root;
BiTreeNode* Create(string s, int& i)
{
BiTreeNode* t = nullptr;
if (s[i] != '#')
{
t = new BiTreeNode;
t->data = s[i];
t->lchild = Create(s, ++i);
t->rchild = Create(s, ++i);
}
else
{
t = new BiTreeNode;
t->data = '#';
t->lchild = nullptr;
t->rchild = nullptr;
}
return t;
}
public:
void Create(string s)
{
int i = 0;
root = Create(s, i);
}
void test(string s)
{
queue<BiTreeNode*> q;
int index = 0;
q.push(root);
while (index != s.length())
{
if (q.front() != nullptr)//空指针直接跳过判断,且空指针无左右孩子,不需要入队列
{
if (q.front()->data != s[index])
{
cout << "NO" << endl;
return;
}
q.push(q.front()->lchild);
q.push(q.front()->rchild);
}
q.pop();
index++;
}
cout << "YES" << endl;
}
};
int main()
{
int t;
cin >> t;
while (t--)
{
string s1, s2;
BiTree mytree;
cin >> s1 >> s2;
mytree.Create(s2);
mytree.test(s1);
}
return 0;
}