您的位置:首页 > 其它

PAT-A1127. 二叉树-中序后序建树,Z字遍历

2017-03-20 21:29 375 查看
题目链接:https://www.patest.cn/contests/pat-a-practise/1127

Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences. And it is a simple standard routine to print the numbers in level-order. However, if you think the problem is too simple, then you are too naive. This time you are supposed to print the numbers in “zigzagging order” – that is, starting from the root, print the numbers level-by-level, alternating between left to right and right to left. For example, for the following tree you must output: 1 11 5 8 17 12 20 15.



Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<= 30), the total number of nodes in the binary tree. The second line gives the inorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the zigzagging sequence of the tree in a line. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

8
12 11 20 17 1 15 8 5
12 20 17 11 15 8 5 1


Sample Output:

1 11 5 8 17 12 20 15


中序后序建树,或前序中序建树,主要是理清思路,前序的第一个结点或后序的最后一个结点是根结点,根据根结点分割中序,左右子数组分别就是左右子树,然后再将子数组对应前序或后序数组中寻找该子树的根结点,循环如此。

Z字形遍历的关键点在于层序遍历并分层输出,分层的方法在上一篇博客中已经讲了,就是标记每层最左边的结点,在输出过程中根据层数选择正序或倒序输出即可。

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

struct BTree {
int data;
BTree* lchild;
BTree* rchild;
};
BTree* T;
int indata[35];
int posdata[35];

BTree* Construct(int* posBegin, int* inBegin, int len){
BTree* root = new BTree();
root->data = posBegin[len-1];
root->lchild = NULL;
root->rchild = NULL;
int* rootInorder = inBegin;
while (rootInorder <= inBegin+len && *rootInorder != root->data) {
++rootInorder;
}
int leftLen = (int)(rootInorder - inBegin);
int rightLen = len - leftLen - 1;
int* rightPosBegin = posBegin + leftLen;

if(leftLen > 0){
root->lchild = Construct(posBegin, inBegin, leftLen);
}
if(rightLen > 0){
root->rchild = Construct(rightPosBegin, rootInorder+1, rightLen);
}

return root;
}

void LevelOrder(BTree* root){
queue<BTree*> qt;
vector<int> printOut;
qt.push(root);
int cnt = 0;
BTree* left = NULL;
bool findLeft = false;

while (!qt.empty()) {
BTree* tr = qt.front();
qt.pop();
if(tr == left) {
if(!(cnt & 1)) reverse(printOut.begin(), printOut.end());
for(int i = 0; i < printOut.size(); ++i){
cout << printOut[i] << " ";
}
findLeft = false;
left = NULL;
printOut.clear();
cnt++;
}
printOut.push_back(tr->data);
if(tr->lchild){
qt.push(tr->lchild);
if(!findLeft){
findLeft = true;
left = tr->lchild;
}

}
if(tr->rchild){
qt.push(tr->rchild);
if(!findLeft){
findLeft = true;
left = tr->rchild;
}
}

}
if(!(cnt & 1)) reverse(printOut.begin(), printOut.end());
for(int i = 0; i < printOut.size(); ++i){
cout << printOut[i];
if(i<printOut.size()-1)
cout << " ";
else
cout << endl;
}

}

int main()
{
int n;
cin >> n;
for(int i = 0; i < n; ++i)
cin >> indata[i];
for(int i = 0; i < n; ++i)
cin >> posdata[i];
T = Construct(posdata, indata, n);
LevelOrder(T);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐