An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.
Figure 1
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: "Push X" where X is the index of the node being pushed onto the stack; or "Pop" meaning to pop one node from the stack.
Output Specification:
For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.
Sample Input:
6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop
Sample Output:
3 4 2 6 5 1
思路:观察发现进栈的数字顺序是先序遍历的顺序,出栈的数字顺序是中序遍历,根据先序和中序建树,再后序遍历。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <vector>
using namespace std;
// 进栈顺序是先序,出栈顺序是中序
typedef struct Node
{
int data;
Node* left;
Node* right;
}node;
vector<int> preOrder;
vector<int> inOrder;
vector<int> postOrder;
node* create(int preL, int preR, int inL, int inR)
{
if(preL > preR) return nullptr;
node* root = new node;
root->data = preOrder[preL];
int k;
for(k = inL; k <= inR; k++)
{
if(inOrder[k] == preOrder[preL])
break;
}
int leftNum = k - inL;
// 左子树在先序遍历中的范围: [preL + 1, preL + leftNum]
// 左子树在中序遍历中的范围: [inL, k - 1]
root->left = create(preL + 1, preL + leftNum, inL, k - 1);
// 右子树在先序遍历中的范围: [preL + leftNum + 1, preR]
// 右子树在中序遍历中的范围: [k + 1, inR]
root->right = create(preL + leftNum + 1, preR, k + 1, inR);
return root;
}
// 后序遍历二叉树
int num = 0;
void postTraversal(node* root)
{
if(root == nullptr) return;
postTraversal(root->left);
postTraversal(root->right);
if(num != 0)
printf(" ");
printf("%d", root->data);
num++;
}
int main()
{
int n;
stack<int> s;
cin >> n;
getchar();
for(int i = 0; i < n * 2; i++)
{
# if 0
// 这种写法最后一个点不过
char tem[30]; // 保存每一行的输入
cin.getline(tem, 30);
if(strlen(tem) == 3) // Pop
{
inOrder.push_back(s.top());
s.pop();
}
else
{
s.push(tem[5] - '0');
preOrder.push_back(s.top());
}
#endif // 0
char str[10];
scanf("%s", str);
if(strcmp(str, "Push") == 0)
{
int d;
scanf("%d", &d);
s.push(d);
preOrder.push_back(d);
}
else
{
inOrder.push_back(s.top());
s.pop();
}
}
// 现在preOrder中保存的是树的先序遍历, inOrder保存的是树的中序遍历
node* root = create(0, n - 1, 0, n - 1); // 根据先序和中序建树
postTraversal(root); // 后序遍历二叉树,结果保存在postOrdere中
return 0;
}