“侧影”就是从左侧或者右侧去观察物体所看到的内容。例如上图中男生的侧影是从他右侧看过去的样子,叫“右视图”;女生的侧影是从她左侧看过去的样子,叫“左视图”。
520 这个日子还在打比赛的你,也就抱着一棵二叉树左看看右看看了……
我们将二叉树的“侧影”定义为从一侧能看到的所有结点从上到下形成的序列。例如下图这棵二叉树,其右视图就是 { 1, 2, 3, 4, 5 },左视图就是 { 1, 6, 7, 8, 5 }。
于是让我们首先通过一棵二叉树的中序遍历序列和后序遍历序列构建出一棵树,然后你要输出这棵树的左视图和右视图。
输入格式:
输入第一行给出一个正整数 N (≤20),为树中的结点个数。随后在两行中先后给出树的中序遍历和后序遍历序列。树中所有键值都不相同,其数值大小无关紧要,都不超过 int 的范围。
输出格式:
第一行输出右视图,第二行输出左视图,格式如样例所示。
输入样例:
8
6 8 7 4 5 1 3 2
8 5 4 7 6 3 2 1输出样例:
R: 1 2 3 4 5
L: 1 6 7 8 5
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <queue>
using namespace std;
int n, inOrder[30], postOrder[30]; //中序遍历序列,后序遍历序列
vector<int> seel, seer; //左视图,右视图
typedef struct biTreeNode { //定义二叉树结点
int key;
biTreeNode* lchild;
biTreeNode* rchild;
}biTree, * BiTree;
void creatBiTree(BiTree& T, int pl, int pr, int il, int ir)//建立二叉树:根节点地址,该树后序遍历序列,该树中序遍历序列
{
T = (biTreeNode*)malloc(sizeof(biTreeNode));
T->key = postOrder[pr]; //当前结点的值等于后序遍历序列的最后一个值
int k; //找到key值在中序遍历序列中的位置
for (int i = 0; i < n; i++) {
if (inOrder[i] == T->key) {
k = i;
break;
}
}
if (k > il) creatBiTree(T->lchild, pl, k - il + pl - 1, il, k - 1);
else T->lchild = NULL;
if (k < ir) creatBiTree(T->rchild, pr - ir + k, pr - 1, k + 1, ir);
else T->rchild = NULL;
return;
}
void FloorPrint(BiTree& T) //对二叉树层序遍历
{
queue<BiTree> temp;//储存二叉树的结点地址
temp.push(T); //根结点入队
BiTree temp2;
while (!temp.empty()) {
int len = temp.size();
for (int i = 0; i < len; i++) {
temp2 = temp.front();
if (i == 0) //本层最左结点
seel.push_back(temp2->key);
if (i == len - 1) //本层最右结点(不能用else if,如果本层只有一个结点,那么最左最右结点相同)
seer.push_back(temp2->key);
temp.pop(); //队头出队
if (temp2->lchild) //左子树入队
temp.push(temp2->lchild);
if (temp2->rchild) //右子树入队
temp.push(temp2->rchild);
}
//本层均出队,下一层入队完毕
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) { //获取中序遍历序列
cin >> inOrder[i];
}
for (int i = 0; i < n; i++) { //获取后序遍历序列
cin >> postOrder[i];
}
BiTree head; //创建头指针,指向二叉树的根结点
creatBiTree(head, 0, n - 1, 0, n - 1); //根据后序遍历序列和中序遍历序列建立二叉树
FloorPrint(head); //层序遍历,同时记录每层最左最右结点key值
cout << "R:";
for (int i : seer) {
cout << " " << i;
}
cout << endl;
cout << "L:";
for (int i : seel) {
cout << " " << i;
}
cout << endl;
return 0;
}
注意事项:
和 “L2-006 树的遍历” 类似,在层序遍历的基础上记录每层边缘的结点key值。
注意某层可能只有一个结点。
如有问题,欢迎提出。