Figure 1
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.
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.
6 Push 1 Push 2 Push 3 Pop Pop Push 4 Pop Pop Push 5 Push 6 Pop Pop
3 4 2 6 5 1
//AC代码:
#include<stdio.h>
int lch[100],rch[100],
pre[100],inorder[100],sum=0,v[100];
int build(int,int,int,int);
void postOrder(int,int);
int main(){
//freopen("input.txt","r",stdin);
int n,i,x,c1=0,c2=0,stack[100],c=-1;
for(scanf("%d",&n),i=0;i<2*n;i++){
char in[100];
scanf("%s",in);
if(in[1]=='u')
scanf("%d",&x),
pre[c1]=c1+1,stack[++c]=++c1,v[c1]=x;
else inorder[c2++]=stack[c--];
}
int root=build(0,c1-1,0,c2-1);
postOrder(root,n);
}
int build(int l1,int r1,int l2,int r2){
if(l1>r1) return 0;
int root=pre[l1],i,cnt=0;
for(i=l2;inorder[i]!=root;cnt++,i++);
lch[root]=build(l1+1,l1+cnt,l2,i-1);
rch[root]=build(l1+cnt+1,r1,i+1,r2);
return root;
}
void postOrder(int x,int n){
if(!x) return;
postOrder(lch[x],n);
postOrder(rch[x],n);
printf("%d",v[x]),sum++;
if(sum-n) printf(" ");
else printf("\n");
}
Push 1 //结点编号为1 键值为1 Push 2 //结点编号为2 键值为2 Push 3 Pop //编号为3的结点被中序遍历到 Pop Push 4 Pop Pop Push 5 Push 6 Pop Pop
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
const int maxn = 60;
int cnt=0, root=0, n, lch[maxn], rch[maxn];
bool flag = true;
void build(int lroot, int *a){
if(cnt > 2*n-1) return;
string s;
cin >> s;
if(s[1] == 'o') {
cnt ++;
return;
}
if(s[1] == 'u'){
int num;
cnt ++;
cin >> num;
a[lroot] = num;
build(num, lch);
build(num, rch);
}
}
void init(){
string s;
cin >> s;
if(s[1] == 'o') {
cnt ++;
return;
}
if(s[1] == 'u'){
cnt ++;
cin >> root;
build(root, lch);
build(root, rch);
}
}
void post_order(int proot){
if(proot == 0) return;
post_order(lch[proot]);
post_order(rch[proot]);
if(flag) printf("%d", proot);
else printf(" %d", proot);
flag = false;
}
int main(){
memset(lch, 0, maxn);
memset(rch, 0, maxn);
scanf("%d", &n);
init();
if(root) post_order(root);
cout << endl;
return 0;
} 数组实现树,代码较为简单!
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <map>
#include <algorithm>
#include <functional>
#include <stdio.h>
#include <limits.h>
using namespace std;
// 树节点定义
struct TreeNode
{
TreeNode(int v) : val(v)
{
left = NULL;
right = NULL;
}
int val;
TreeNode *left, *right;
};
// 从先序遍历序列和中序遍历序列中构建一棵树
TreeNode* create_tree(
const vector<int> &pre_order, int pre_start, int pre_end,
const vector<int> &in_order, int in_start, int in_end,
const map<int, int> &h_inorder_pos)
{
if (pre_start >= pre_end || in_start >= in_end)
return NULL;
int root_val = pre_order[pre_start];
int root_inorder_pos = h_inorder_pos.at(root_val);
int left_size = root_inorder_pos - in_start;
TreeNode *root = new TreeNode(root_val);
root->left = create_tree(
pre_order, pre_start + 1, pre_start + left_size + 1,
in_order, in_start, root_inorder_pos, h_inorder_pos);
root->right = create_tree(
pre_order, pre_start + left_size + 1, pre_end,
in_order, root_inorder_pos + 1, in_end, h_inorder_pos);
return root;
}
// 二叉树后序遍历,pred 为对节点的访问方法
void post_order_traverse(TreeNode *root, vector<int> &post_order)
{
if (!root)
return;
post_order_traverse(root->left, post_order);
post_order_traverse(root->right, post_order);
post_order.push_back(root->val);
}
void destroy_tree(TreeNode *root)
{
if (!root)
return;
destroy_tree(root->left);
destroy_tree(root->right);
delete root;
root = NULL;
}
int main(int argc, char * const argv[])
{
int n;
cin >> n;
vector<int> pre_order;
vector<int> in_order;
stack<int> s;
int x;
string operation;
while (cin >> operation)
{
if (operation == "Push")
{
cin >> x;
pre_order.push_back(x); // 将每次 Push 的节点保存到先序遍历序列
s.push(x);
}
else // Pop
{
in_order.push_back(s.top()); // 保存到中序遍历序列
s.pop();
}
}
// 用 Hash 表保存每个节点在中序遍历序列中的位置
map<int, int> h_inorder_pos;
for (int i = 0; i < in_order.size(); ++i)
{
h_inorder_pos[in_order[i]] = i;
}
// 构建树
TreeNode *tree = create_tree(pre_order, 0, pre_order.size(), in_order, 0, in_order.size(), h_inorder_pos);
vector<int> post_order; // 后序遍历序列
// 生成后序遍历序列
post_order_traverse(tree, post_order);
// 后序遍历删除树
destroy_tree(tree);
// 输出后序遍历序列
for (int i = 0; i < post_order.size(); ++i)
{
cout << (i == 0 ? "" : " ") << post_order[i];
}
cout << endl;
return 0;
}
class TreeNode: def __init__(self, data): self.data = data self.lchild = None self.rchild = None class BinaryTree: def __init__(self, root=None): self.root = root def postOrder(self, tree): if tree is not None: self.postOrder(tree.lchild) self.postOrder(tree.rchild) self.visit(tree) def visit(self, tree): print data[tree.data], def constructBinaryTree(pre, s1, e1, inOrder, s2, e2): if s1 > e1: return None idx = inOrder.index(pre[s1]) root = TreeNode(pre[s1]) root.lchild = constructBinaryTree(pre, s1+1, s1+idx-s2, inOrder, s2, idx-1) root.rchild = constructBinaryTree(pre, s1+idx-s2+1, e1, inOrder, idx+1, e2) return root data = []; idx = []; num = 0 preOrder = []; inOrder = [] N = int(raw_input()) for i in range(N*2): line = raw_input().strip().split() if line[0] == 'Push': data.append(int(line[1])) preOrder.append(num) idx.append(num) num += 1 else: inOrder.append(idx.pop()) bt = BinaryTree(constructBinaryTree(preOrder, 0, N-1, inOrder, 0, N-1)) bt.postOrder(bt.root)
#include <iostream>
#include <vector>
using namespace std;
struct node {
int v;
node *left, *right, *par;
bool pop;
node(int val):v(val) {
left = NULL;
right = NULL;
par = NULL;
pop = false;
}
};
int n, inNum;
string inOp;
vector<int> postVec; // 存储后序遍历的序列
void postTravel(node *root) {
if(root == NULL)
return;
postTravel(root->left);
postTravel(root->right);
postVec.push_back(root->v);
}
void destoryTree(node *root) {
if(!root)
return;
destoryTree(root->left);
destoryTree(root->right);
delete root;
root = NULL;
}
int main() {
cin >> n;
node *root = NULL;
node *cur = NULL;
for(int i=1; i <= 2*n; ++i) {
cin >> inOp;
if(inOp.at(inOp.length()-1) == 'h') { // Push
cin >> inNum;
node *n = new node(inNum);
if(cur == NULL) {
root = n;
cur = root;
} else {
if(cur->left == NULL)
cur->left = n;
else
cur->right = n;
n->par = cur;
cur = n;
}
} else { // Pop
while(cur->pop)
cur = cur->par;
cur->pop = true;
}
}
postTravel(root);
for(int i=0; i<postVec.size(); ++i)
cout << (i==0 ? "" : " ") << postVec[i]; //注意输出格式
cout << endl;
destoryTree(root);
return 0;
}
#include <iostream>
#include <cstdlib>
#include <string>
#include <stack>
using namespace std;
bool isFirst = true;
typedef struct BinaryTree {
int data;
BinaryTree* left;
BinaryTree* right;
} BiTree;
void postOrderTravel(BiTree* tree) {
if (tree != NULL) {
postOrderTravel(tree->left);
postOrderTravel(tree->right);
if(isFirst) {
cout << tree->data;
isFirst = false;
} else {
cout << " " << tree->data;
}
}
}
int main() {
BiTree *root, *index, *parrent;
int lr = 0;
root = (BiTree*)malloc(sizeof(BiTree));
root->right = NULL;
root->left = NULL;
index = root;
parrent = root;
stack<BiTree*> BiStack;
int count;
cin >> count;
int i = 0;
while (i < count || !BiStack.empty()) {
string order;
cin >> order;
if (order == "Push") {
int data;
cin >> data;
i++;
index->data = data;
BiStack.push(index);
index->left = (BiTree*)malloc(sizeof(BiTree));
parrent = index;
lr = 0;
index = index->left;
index->right = NULL;
index->left = NULL;
}
else if (order == "Pop") {
free(index);
if (lr == 0) {
parrent->left = NULL;
}
else if (lr == 1) {
parrent->right = NULL;
}
BiTree* top = BiStack.top();
BiStack.pop();
if (i == count && BiStack.empty()) {
break;
}
top->right = (BiTree*)malloc(sizeof(BiTree));
parrent = top;
lr = 1;
index = top->right;
index->right = NULL;
index->left = NULL;
}
}
postOrderTravel(root);
return 0;
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String index = "left";//记录当前是在左孩子节点处插入,还是在右孩子节点处插入
Node root = null;
Deque<Node> deque = new ArrayDeque<>();
//构造出原树的结构。
for (int i = 0; i < n * 2; i++) {
String command = sc.next();
if (command.equals("Push")) {
int val = sc.nextInt();
Node node = new Node(val);
if (deque.isEmpty()) {//如果栈为空,记录根结点
root = node;
deque.push(node);
} else {
if (index.equals("left")) {
deque.peek().left = node;
} else {
deque.peek().right = node;
deque.pop();//如果是插入右孩子结点,这将去除当前栈顶处的结点
index = "left";
}
deque.push(node);
}
} else {//command="Pop"
if (index.equals("left")) {
index = "right";
} else {
deque.pop();
}
}
}
List<Integer> ans = new ArrayList<>();
//后序遍历原树。
postorder(root, ans);
for (int i = 0; i < ans.size(); i++) {
if(i!=ans.size()-1)
System.out.print(ans.get(i)+" ");
else
System.out.print(ans.get(i));
}
}
static void postorder(Node node, List<Integer> ans) {
if (node == null) return;
postorder(node.left, ans);
postorder(node.right, ans);
ans.add(node.val);
}
}
class Node {
int val;
Node left;
Node right;
Node(int val) {
this.val = val;
}
}
PAT能过,牛客过不了,服了
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
const int N = 40;
int n, pos[N];
stack<int> stk;
vector<int> pre, in, post;
int l[N], r[N];
int build(int il, int ir, int pl, int pr)
{
int root = pre[pl];
int k = pos[root];
if (il < k) l[root] = build(il, k - 1, pl + 1, pl + k - il);
if (ir > k) r[root] = build(k + 1, ir, pr - ir + k + 1, pr);
return root;
}
void postorder(int root)
{
if (l[root]) postorder(l[root]);
if (r[root]) postorder(r[root]);
post.push_back(root);
}
int main()
{
cin >> n;
for (int i = 0; i < 2 * n; i ++)
{
string op; int t;
cin >> op;
if (op == "Push")
{
cin >> t;
stk.push(t);
pre.push_back(t);
}
else
{
in.push_back(stk.top());
stk.pop();
}
}
for (int i = 0; i < n; i ++) pos[in[i]] = i;
int root = build(0, n - 1, 0, n - 1);
postorder(root);
cout << post[0];
for (int i = 1; i < n; i ++) cout << ' ' << post[i];
return 0;
}
#include<stack>
#include <iostream>
#include<stdio.h>
using namespace std;
int N,pcount=0,icount=0;
//设置uniquepre和uniquein是因为 节点的value值不唯一
int pre[40], in[40], uniquepre[40], uniquein[40];
stack<int>s,b;
struct node {
int value;
node* left;
node* right;
};
int flag = 1;
//后续遍历二叉树,先左后右再根
void postorder(int h1,int t1,int h2,int t2)
{
//先在中序遍历序列中找出根节点的位置
int mid = h2;
for (; uniquein[mid] != uniquepre[h1]; mid++);
//遍历左子树
if(mid>h2)
postorder(h1 + 1, mid + h1 - h2, h2, mid - 1);
if(mid<t2)
postorder(t1 - t2 + mid + 1, t1, mid + 1, t2);
if (flag)
{
cout << pre[h1];
flag = 0;
}
else
cout << ' ' << pre[h1];
}
int main()
{
cin >> N;
int a,len = 2 * N;
char temp[10];
//从输入数据中提取出先序遍历和中序遍历序列
for (int i = 0; i < len; i++)
{
scanf("%s", temp);
if (temp[1] == 'u')//Push操作
{
scanf("%d", &a);
uniquepre[pcount] = pcount;
b.push(pcount);
pre[pcount++] = a;
s.push(a);
continue;
}
else if (temp[1] == 'o')
{
int x = s.top();
s.pop();
int y = b.top();
b.pop();
uniquein[icount] = y;
in[icount++] = x;
}
}
postorder(0, N - 1, 0, N - 1);
return 0;
}
a = int(input())
c = input().split()[1]
d = {c:['','']}
m = [[c,1]]
for i in range(a * 2 - 1):
b = input()
if b != 'Pop':
b = b.split()[1]
d[m[-1][0]][m[-1][1]] = b
d[b] = ['','']
m[-1][1] -= 1
if m[-1][1] == -1:
del m[-1]
if b != 'Pop':
m.append([b,1])
i,n,p = 0,[[c,0]],[]
while True:
while n[-1][1] == 2:
del n[-1]
p.append(n[-1][0])
if len(p) == a:
print(' '.join(p[::-1]))
break
while d[n[-1][0]][n[-1][1]] == '':
n[-1][1] += 1
if n[-1][1] == 2:
del n[-1]
n.append([d[n[-1][0]][n[-1][1]],0])
n[-2][1] += 1
if n[-2][1] == 2:
del n[-2]
package pat.t0907;
import java.util.Scanner;
import java.util.Stack;
public class T4004 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Node root = null;
Node current=null;
Stack<Node> stack = new Stack<>();
for (int i = 0; i < 2 * n; i++) {
String line = sc.nextLine().trim();
if (line.startsWith("Push")) {//"Push X"
if (root == null) {
root = new Node(Integer.parseInt(line.substring(5).trim()));
current=root;
stack.push(current);
continue;
}
if (current.left== null) {
current.left = new Node(Integer.parseInt(line.substring(5).trim()));
current=current.left;
stack.push(current);
} else if (current.right== null) {
current.right = new Node(Integer.parseInt(line.substring(5).trim()));
current=current.right;
stack.push(current);
}
} else if (stack.size() > 0) {//"Pop"
current=stack.pop();
}
}
sc.close();
if(root!=null) {
StringBuilder sb=root.toStringPostorder();
sb.deleteCharAt(sb.length()-1);
System.out.print(sb);
}
}
}
class Node {
int data;
Node left;
Node right;
Node(int data) {
this.data = data;
this.left = null;
this.right = null;
}
public StringBuilder toStringPostorder() {//后序遍历
StringBuilder sb=new StringBuilder();
if(this.left!=null) {
sb.append(this.left.toStringPostorder());
}
if(this.right!=null) {
sb.append(this.right.toStringPostorder());
}
sb.append(this.data+" ");
return sb;
}
}
关键在于两个变量。current和stack,一个是当前操作的节点,一个是节点栈。
class Node: def __init__(self,value,left,right): self.value = value self.left = left self.right = right def construct_tree(pre_order,s1,e1, mid_order,s2,e2): if s1>e1: return None i = mid_order.index(pre_order[s1]) root_data = pre_order[s1] left = construct_tree(pre_order,s1+1,s1+i-s2, mid_order,s2,i-1) right = construct_tree(pre_order,s1+i-s2+1,e1, mid_order,i+1,e2) return Node(root_data, left, right) def post(root): """递归后序遍历""" if root == None: return queue = [] queue.append(root) while queue: node = queue.pop(0) if node.left: post(node.left) if node.right: post(node.right) print(data[node.value], end='') #class Tree: # def __init__(self,root=None): # self.root = root # def post(self,tree): # """递归后序遍历""" # if tree is None: # return # queue = [] # queue.append(tree) # while queue: # node = queue.pop(0) # if node.left: # self.post(self,node.left) # if node.right: # self.post(self,node.right) # print(data[node.value], end=' ') n = input() n = int(n) num = 0 pre,inord,tem,data = [],[],[],[] for i in range(2*n): t = input().split() if t[0]=="Push": pre.append(num) tem.append(num) data.append(int(t[1])) num+=1 else: inord.append(tem.pop()) root = construct_tree(pre,0,n-1,inord,0,n-1) post(root)
这题和pat的不是一道题
pat通过的代码::
#include<iostream>
#include<fstream>
#include<stack>
#include<vector>
#include<string>
#include<algorithm>
#include<queue>
#define N 100
using namespace std;
int parent[N];
vector<int> inorder;
queue<int> route;
void ReBuild(int root,vector<int>::iterator begin,vector<int>::iterator end)
{ vector<int>::iterator divid=find_if(begin,end,[root](int a)->bool{ return a==root;}); if(divid!=end) { vector<int>::iterator lt,rt; lt=find_if(begin,divid,[root](int a)->bool{ return parent[a]==root;}); if(lt!=divid) ReBuild(*lt,begin,divid); rt=find_if(divid+1,end,[root](int a)->bool{ return parent[a]==parent[root];}); if(rt!=end) ReBuild(*rt,divid+1,end); } route.push(root); }
int main()
{ ifstream f("Input.txt"); cin.rdbuf(f.rdbuf()); int num; cin>>num; int root; fill(parent,parent+N,0); stack<int> operation; for(int i=0;i<2*num;i++) { string op; int id; cin>>op; if(op=="Push") { cin>>id; operation.push(id); if(i==0) root=id; } else { int node=operation.top(); operation.pop(); inorder.push_back(node); if(operation.size()==0) parent[node]=0; else parent[node]=operation.top(); } } ReBuild(root,inorder.begin(),inorder.end()); while(route.size()) { if(route.size()==1) cout<<route.front(); else cout<<route.front()<<" "; route.pop(); } return 0;
}
思路:这道题有一个坑点,就是创建二叉树的时候你要保证你的树没有相同的值,否则会报错。
我才用了就是建树的时候遇到相同的值后面加上一个".";
#include <ios>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
using namespace std;
vector<string> DLR(1);
vector<string> LDR(1);
int sum = 0;
typedef struct tagNODE {
string value;
struct tagNODE *pLeft, *pRight;
}NODE;
// 先序 和 中序 建立 树
NODE* GenBinTree(const int DLRStart, const int DLREnd, const int LDRStart, const int LDREnd)
{
if(DLRStart > DLREnd || LDRStart > LDREnd)
{
return NULL;
}
if (DLRStart == DLR.size())
return NULL;
string rootValue = DLR[DLRStart];
NODE *root = new NODE;
root->value = rootValue;
root->pLeft = root->pRight = NULL;
int k;
for (k = LDRStart; k <= LDREnd; k++)
{
if (LDR[k] == DLR[DLRStart])
break;
}
int nl = k - LDRStart;
root->pLeft = GenBinTree(DLRStart + 1, DLRStart + nl, LDRStart, k-1);
root->pRight = GenBinTree(DLRStart + nl + 1, DLREnd, k + 1, LDREnd);
return root;
}
void PostOrder(NODE *root)
{
if (root != NULL)
{
PostOrder(root->pLeft);
PostOrder(root->pRight);
if (root->value.find(".") != string::npos)
{
root->value = root->value.substr(0, root->value.find("."));
}
if (--sum != 0)
cout << root->value << " ";
else
cout << root->value << endl;
}
}
int main()
{
ifstream ifile("test.txt", ios::out | ios::in);// 文件要先存在
string line;
int n;
while (cin >> n)
{
string temp;
sum = n;
string value;
NODE *p = new NODE[n];
stack<string> Mystack;
for (int i = 0; i < n * 2; i++)
{
cin >> temp;
if (temp == "Push")
{
cin >> value;
for (int i = 1; i < DLR.size(); i++)
{
if (DLR[i] == value)
{
value = value + ".";
}
}
DLR.push_back(value);
Mystack.push(value);
}
if (temp == "Pop")
{
LDR.push_back(Mystack.top());
Mystack.pop();
}
}
/*
for (auto c : DLR)
{
cout << c << " ";
}
cout << endl;
for (auto c : LDR)
{
cout << c << " ";
}
cout << endl;
*/
NODE *root = GenBinTree(1, LDR.size() - 1, 1, LDR.size() - 1);
// 后根遍历
PostOrder(root);
}
ifile.close();
//cout.close();
system("pause");
}
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() = default;
TreeNode(const int v) : val(v)
{
left = NULL;
right = NULL;
}
};
TreeNode* RecoveryTree(const vector<int> & preOrder, const int b1, const int e1,
const vector<int> & inOrder, const int b2, const int e2)
{
if (b1 > e1)
return NULL;
int idx = distance(inOrder.begin(), find(inOrder.begin(), inOrder.end(), preOrder[b1]));
TreeNode* root = new TreeNode(preOrder[b1]);
root->left = RecoveryTree(preOrder, b1 + 1, b1 + idx - b2, inOrder, b2, idx - 1);
root->right = RecoveryTree(preOrder, b1 + idx - b2 + 1, e1, inOrder, idx + 1, e2);
return root;
}
TreeNode* BuildTree(int *N)
{
TreeNode* root = NULL;
//fstream f1("test1.txt");
//f1 >> *N;
stack<int> s;
vector<int> preOrder, inOrder;
string line, word;
string Pop("Pop"), Push("Push");
int id;
getline(cin, line);
istringstream in(line);
in >> *N;
for (int i = 0; i < *N * 2; i++)
{
//f1 >> word;
getline(cin, line);
istringstream in(line);
in >> word;
if (word == Push)
{
//f1 >> id;
in >> id;
s.push(id);
preOrder.push_back(id);
}
else if (word == Pop)
{
int a = s.top();
s.pop();
inOrder.push_back(a);
}
}
root = RecoveryTree(preOrder, 0, preOrder.size() - 1, inOrder, 0, inOrder.size() -1);
return root;
}
void PostOrderTraversal(const TreeNode * root, int &count, const int N)
{
if (root)
{
PostOrderTraversal(root->left, count, N);
PostOrderTraversal(root->right, count, N);
count++;
if (count != N)
cout << root->val << " ";
else
cout << root->val << endl;
}
}
void DestroyTree(TreeNode * root)
{
if (!root)
return;
DestroyTree(root->left);
DestroyTree(root->right);
delete root;
root = NULL;
}
int main()
{
TreeNode* root;
int count = 0;
int N = 0;
root = BuildTree(&N);
PostOrderTraversal(root, count, N);
DestroyTree(root);
return 0;
}
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
class Tree {
int val;
Tree left;
Tree right;
public Tree(int val) {
this.val = val;
}
public Tree() {}
}
public class Main {
public static void postorder(Tree root, ArrayList list) {
if (root != null) {
postorder(root.left, list);
postorder(root.right, list);
list.add(root.val);
}
}
public static void main(String args[]) {
ArrayList list = new ArrayList();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //input N nodes
Stack stack = new Stack();
String str = new String("");
Tree[] root = new Tree[n + 1];
int index = 0;
int popVal = -1;
for (int i = 0; i < 2 * n; ++i) {
str = sc.next();
if (str.equals("Push")) {
int value = sc.nextInt();
if (i == 0) {
root[++index] = new Tree(value);
} else if (i != 0 && popVal == -1) {
root[(Integer) stack.peek()].left = root[++index] = new Tree(value);
}
if (popVal != -1) {
root[popVal].right = root[++index] = new Tree(value);
}
stack.push(index);
popVal = -1;
} else {
popVal = (Integer) stack.peek();
stack.pop();
}
}
postorder(root[1], list);
for (int i = 0; i < list.size(); ++i) {
if (i != list.size() - 1)
System.out.print(list.get(i) + " ");
else
System.out.print(list.get(i));
}
}
}
step one: 首先根据输入,构造出原树的结构。
step two: 后序遍历原树。
关于第一步,需要观察Push和Pop,找出构造原树的方法:
每次Push相当于插入节点,Pop相当于回朔,为了便于回朔的实现,根据最后Pop出的节点的 Id,从已经构造的原树中查找应该回朔到的节点。
关于第二步,如果有n个节点,需要输出n-1个空格,经过观察发现,打印每个节点时,后面跟一个空格,根节点除外,这样就可以打印符合要求的结果,所以只需要能判断是否为根节点即可。
代码如下:
import java.io.PrintStream; import java.util.Scanner; import java.util.Stack; public class Main { // 树的定义 public class Tree{ int node; int id; Tree left; Tree right; public Tree(int id, int node){ this.id = id; this.node = node; left = right = null; } } public void treeTraveral(){ Tree root = recoverTree(); // 后序打印树 if(root!=null){ postPrintTree(root, root.id); } } public Tree recoverTree(){ Stack<Integer> stack = new Stack<>(); Tree root = null,treeIndex=null; int n = Integer.valueOf(in.nextLine()); Integer val,popId=null; int id = 1; // 构造树的结构 for(int i=0;i<2*n;++i){ String line = in.nextLine(); if(line.startsWith("Push")){ val = Integer.valueOf(line.substring(5)); stack.push(id); if(root == null){ root = new Tree(id++,val); treeIndex = root; }else{ if(popId!=null){ treeIndex = getNodeFromValue(root, popId); } Tree tmp = new Tree(id++,val); if(treeIndex.left == null){ treeIndex.left = tmp; }else{ treeIndex.right = tmp; } treeIndex = tmp; } popId=null; }else{ popId = stack.pop(); } } return root; } /* * 根据节点值,获取树中该节点的引用 * 注意:节点值唯一 */ public Tree getNodeFromValue(Tree root, int id){ // 边界 if(root == null) return null; if(root.id == id ) return root; //递归搜索左子树 Tree result = getNodeFromValue(root.left, id); //递归搜索右子树 if(result==null){ result = getNodeFromValue(root.right, id); } return result; } /* * 后序打印树中的节点值 */ public void postPrintTree(Tree root, int rootId){ if(root==null) return; if(root.left == null && root.right == null){ out.print(root.node); if(root.id!=rootId){ out.print(" "); } return; } // 递归打印左子树 if(root.left!=null){ postPrintTree(root.left,rootId); } // 递归打印右子树 if(root.right!=null){ postPrintTree(root.right,rootId); } // 打印父节点 out.print(root.node); if(root.id!=rootId){ out.print(" "); } } public static Scanner in = new Scanner(System.in); public static PrintStream out = System.out; public static void main(String[] args) { Main t = new Main(); t.treeTraveral(); } }