1935. 二叉树重建
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
对于二叉树T,可以递归定义它的先序遍历、中序遍历和后序遍历如下: PreOrder(T)=T的根节点+PreOrder(T的左子树)+PreOrder(T的右子树) InOrder(T)=InOrder(T的左子树)+T的根节点+InOrder(T的右子树) PostOrder(T)=PostOrder(T的左子树)+PostOrder(T的右子树)+T的根节点 其中加号表示字符串连接运算。例如,对下图所示的二叉树,先序遍历为DBACEGF,中序遍历为ABCDEFG。
输入一棵二叉树的先序遍历序列和中序遍历序列,输出它的广度优先遍历序列。
Input
第一行为一个整数t(0<t<10),表示测试用例个数。 以下t行,每行输入一个测试用例,包含两个字符序列s1和s2,其中s1为一棵二叉树的先序遍历序列,s2为中序遍历序列。s1和s2之间用一个空格分隔。序列只包含大写字母,并且每个字母最多只会出现一次。
Output
为每个测试用例单独一行输出广度优先遍历序列。
Sample Input
2 DBACEGF ABCDEFG BCAD CBAD
Sample Output
DBEACGF BCAD
/*********************************************************** * 已知树的先序遍历和中序遍历,输出该树的广度优先遍历; * 解决方案是,先重建这颗树:先求出中序遍历字符串的长度,定义一个Map 类型 * 将中序字符串的每个字母和它在字符串中的位置存到Map中,如:中序字符串为ABC, * 那么将 0-A、1-B、2-C分别存进Map中; * 之后用先序字符串来重建树: * 1、从先序字符串的第一个字母开始,并在中序字符串中找到它的位置 * 2、按照二叉树的排序原则将它插入树中,插入原则,按照字母在中序位置的大小来插; * 重复1、2直到最后一个字母插入; * 至此,树已经重建好,广度优先遍历,需创建一个queue,借助队列数据结构, * 由于队列是先进先出的顺序,因此可以先将左子树入队,然后再将右子树入队。 *这样一来,左子树结点就存在队头,可以先被访问到 *最后输出队列中front的字母就可以了 *************************************************************/ #include <iostream> #include <string> #include <queue> using namespace std; //用一个temp来讲树的顶指针保存下来 bool temp = true; //Map 结构体来保存中序中每个字母及它所在的位置 struct Map { int value; char data; Map() { value = NULL; data = NULL; } } m[1000]; //构建一棵树 struct tree_insert { tree_insert *left, *right; int v; char ch; tree_insert() { left = NULL; right = NULL; } }*sub_root, *first; //树的插入及排序 void Insert(tree_insert *&sub_root, int d, char c) { if (sub_root == NULL) { sub_root = new tree_insert; sub_root->v = d; sub_root->ch = c; //temp来临时记录树的顶指针 if (temp) { first = sub_root; temp = false; } } else if (d < sub_root->v) //左子树遍历 return Insert(sub_root->left, d, c); else //右子树遍历 return Insert(sub_root->right, d, c); } /*void inorder(tree_insert *sub_root) // 后序遍历 { if (sub_root != NULL) { inorder(sub_root->left); inorder(sub_root->right); cout << sub_root->v << sub_root->ch << " "; } }*/ //广度优先遍历 void breadthFirstSearch(tree_insert *sub_root) { queue <tree_insert *> nodeQueue; //树顶指针如队 nodeQueue.push(sub_root); tree_insert * temp_node; while (!nodeQueue.empty()) { temp_node = nodeQueue.front(); //输出字母 cout << temp_node->ch; nodeQueue.pop(); //左子树入队 if (temp_node->left != NULL) nodeQueue.push(temp_node->left); //右子树入队 if (temp_node->right != NULL) nodeQueue.push(temp_node->right); } cout << endl; } int main() { int n; cin >> n; string s1, s2; while (n--) { temp = true; sub_root = NULL; first = NULL; //s1先序、s2中序 cin >> s1 >> s2; int len = s1.length(); // for (int i = 0; i < len; i++) { //保存中序中每个字母及它所在的位置 m[i].value = i; m[i].data = s2[i]; } for (int i = 0; i < len; i++) { char temp = s1[i]; int k = s2.find(temp); Insert(first, m[k].value, m[k].data); } breadthFirstSearch(first); } system("pause"); return 0; }