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 (≤) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2 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:

Push
Push
Push
Pop
Pop
Push
Pop
Pop
Push
Push
Pop
Pop

Sample Output:

     

可以使用堆栈以非递归方式实现顺序二进制树遍历。你的任务是给出这棵树的后序遍历序列。

每个输入文件包含一个测试用例。对于每种情况,第一行包含正整数N(≤ 3 0),它是节点的总数量在树(并且因此节点编号从1到N)。然后接下来是N行,每行描述一种堆栈操作,格式为:“Push X”,其中X是被推入堆栈的节点的索引; 或“Pop”表示从堆栈中弹出一个节点。

对于每个测试用例,在一行中打印相应树的后序遍历序列。保证存在解决方案。所有数字必须用一个空格分隔,并且在行的末尾不能有额外的空格。

先给出大神的思路

对二叉树的中序遍历可以通过使用栈来避免迭代的方法,对于figure1中的6节点树而言,它的栈操作为push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop()。依据这个输入可以生成这个二叉树,要求打印出该树的后序遍历。

解法:

该题要求我们通过中序遍历的栈实现的栈操作来生成二叉树。

如上图,中序遍历的操作流程(其中箭头代表遍历流),我们可以看出:

1.每次push都指向一个新的节点。

2.每次pop都指向一个被抛出的节点。

3.连续的pop-pop或push-push流的方向都相同。

4.连续的push-pop指向同一个叶节点,同时执行方向转弯。(节点3)

5.连续的pop-push经过一个父节点,同时执行方向转弯。(节点2)

6.每个节点只能pop指向一次,push指向一次。(节点4到2直接跳到1)

于是我们就可以通过这些特性来构建二叉树:

1.读入第一次push构建根节点,根节点入栈。

2.读入下一个操作,有两种情况:

(1)push

说明有一个新节点出现,构建一个节点。如果上次操作为push,把该节点设为栈顶的左儿子,节点入栈。如果上次是pop,经过一个父节点,说明应该是生成了父节点的一个儿子,所以将该节点设为上次pop出来的节点的右儿子。

(2)pop

说明正在pop一个节点,不论上次操作是,该次都抛出一个节点。

这是我写的,有点菜

 #include <iostream>
#include <stack>
#include <string>
#include <algorithm>
#define MaxTree 31
#define Null -1
using namespace std; int P[MaxTree];
int num=;
int NUM=;
stack<int> st; struct TreeNode
{
int date;
int Left;
int Right;
}T[MaxTree]; int BuildTree(struct TreeNode T[])
{
int N,m,p,i;
string str,pre;
int Root;
cin>>N;
for(i=;i<*N;i++)
{
cin>>str;
if(str=="Push")
{
cin>>m;
if(i==)
{
Root=;
T[num].date=m;
T[num].Left=Null;
T[num].Right=Null;
st.push(num);
pre=str;
}
else if(pre=="Push")
{
T[num].Left=num+;
num++;
T[num].date=m;
T[num].Left=Null;
T[num].Right=Null;
st.push(num);
pre=str;
}
else if(pre=="Pop")
{
T[p].Right=num+;
num++;
T[num].date=m;
T[num].Left=Null;
T[num].Right=Null;
st.push(num);
pre=str;
}
}
else if(str=="Pop")
{
p=st.top();
st.pop();
pre=str;
}
}
if(N==)
{
Root=Null;
}
return Root;
} void search(int Tree)
{
if(Tree==Null)
return;
search(T[Tree].Left);
search(T[Tree].Right);
P[NUM++]=T[Tree].date;
} int main()
{
int Tree;
Tree=BuildTree(T);
search(Tree);
int i;
for(i=;i<NUM;i++)
{
if(i==)
cout<<P[i];
else
cout<<' '<<P[i];
}
return ;
}

下面是别人用动态链表实现的,值得一看

 #include <cstdio>
#include <stack>
using namespace std; int preorder[], inorder[];
int n, preid = , inid = , cnt = ;
int get(){
char s[];
scanf("%s", s);
if (s[] == 'o') return -;
int a;
scanf("%d", &a);
return a;
}
void build(int preb, int pree, int inb, int ine){
if (preb > pree) return;
int root = preorder[preb];
int inroot = inb;
while (inorder[inroot] != root) ++inroot;
build(preb+, preb+inroot-inb, inb, inroot-);
build(preb+inroot-inb+, pree, inroot+, ine);
if (cnt++ != ) putchar(' ');
printf("%d", root);
}
int main(){
scanf("%d", &n);
stack<int> st;
for (int i = ; i < n*; ++i){
int a = get();
if (a != -){
st.push(a);
preorder[preid++] = a;
}else{
inorder[inid++] = st.top();
st.pop();
}
}
build(, n-, , n-);
return ;
}
 #include <string>
#include <iostream>
#include <stack>
using namespace std; const string PUSH("Push");
const string POP("Pop"); typedef struct Node
{
int data;
Node* left;
Node* right;
Node(int d):data(d), left(NULL), right(NULL){}
}Node; void PostOrderTraverse(Node *root)
{
Node* temp = root;
Node* pre = NULL;
stack<Node*> S;
int flag = ; while(temp || !S.empty())
{
if(temp)
{
S.push(temp);
temp = temp->left;
}
else
{
temp = S.top();
if(temp->right && temp->right != pre)
temp = temp->right;
else
{
if(!flag)
{
flag = ;
cout<< temp->data;
}
else
cout<<" "<<temp->data;
S.pop();
pre = temp;
temp = NULL;
}
}
}
cout<<endl;
} int main()
{
int n, data;
string act;
stack<Node*> S;
Node* root = NULL, *pre = NULL;
int l = , r = ;
cin >> n; //First, build the tree , root of tree is *root.
for(int i=; i <= *n; i++)
{
Node* temp;
cin >> act;
if(act == PUSH)
{
cin >> data;
temp = new Node(data);
if(i == )
{
root = temp;
} S.push(temp);
if(pre)
{
if(l == )
pre->left = temp;
else
pre->right = temp;
}
l = ;
pre = temp;
}
else if(act == POP)
{
pre = S.top();
S.pop();
l = ;
}
} PostOrderTraverse(root); system("pause");
return ;
}

Tree Traversals Again的更多相关文章

  1. Tree Traversals

    Tree Traversals 原题链接 常见的二叉树遍历的题目,根据后序遍历和中序遍历求层次遍历. 通过后序遍历和中序遍历建立起一棵二叉树,然后层序遍历一下,主要难点在于树的建立,通过中序遍历和后序 ...

  2. HDU 1710 二叉树的遍历 Binary Tree Traversals

    Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  3. hdu1710(Binary Tree Traversals)(二叉树遍历)

    Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  4. HDU1710Binary Tree Traversals

    HDU1710Binary Tree Traversals 题目大意:给一个树的前序遍历和中序遍历,要求输出后序遍历. (半年前做这道题做了两天没看懂,今天学了二叉树,回来AC了^ ^) 首先介绍一下 ...

  5. HDU-1701 Binary Tree Traversals

    http://acm.hdu.edu.cn/showproblem.php?pid=1710 已知先序和中序遍历,求后序遍历二叉树. 思路:先递归建树的过程,后后序遍历. Binary Tree Tr ...

  6. 03-树2. Tree Traversals Again (25)

    03-树2. Tree Traversals Again (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue ...

  7. HDU 1710-Binary Tree Traversals(二进制重建)

    Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  8. PAT1086:Tree Traversals Again

    1086. Tree Traversals Again (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...

  9. Binary Tree Traversals(HDU1710)二叉树的简单应用

    Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  10. 【PAT】1020 Tree Traversals (25)(25 分)

    1020 Tree Traversals (25)(25 分) Suppose that all the keys in a binary tree are distinct positive int ...

随机推荐

  1. JQuery图片自适应窗口轮播图(淡入淡出效果)

    <script>var w = $(window).width();//获取窗口宽度var h = $(window).height();//获取窗口高度 $(".box&quo ...

  2. 搭建EOS未完

    纯净机器上部署 EOS 测试网 演示的系统为 Ubuntu 18.04 LTS,内存8g以上,硬盘300g+ clone EOS代码 们以EOS-Mainnet仓库部署,(EOS-Mainnet是部署 ...

  3. JdbcTemplate 配置多数据源(完全照抄,完整)

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  4. 浅析URL(接口测试必备知识)

    笔者最近在开始接触接口测试的工作,接口测试必须了解http协议,但前提是必须要了解URL URL的定义 url是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标 ...

  5. 第二次实验:CC2530平台上GPIO组件的TinyOS编程

    实验二 CC2530平台上GPIO组件的TinyOS编程 实验目的: 加深和巩固学生对于TinyOS编程方法的理解和掌握 让学生理解和掌握CC2530的GPIO及外部中断,及其TinyOS编程方法 学 ...

  6. opencv+qt+vtk,编程时报错'detail':ambiguous symbol

    解决办法: 把#include <vtkSmartPointer.h>放到所有头文件的最前面:

  7. Python的内置方法——补充

    七 __setitem__,__getitem__,__delitem__ class Foo: def __init__(self,name): self.name=name def __getit ...

  8. application————web

    application 作用域: 只要web服务器不关闭就一直存在 统计页面的统计次数 一个用户 多次刷新也统计 多个用户访问 思路: 需要一个变量 count 记录index.jsp访问次数 方法 ...

  9. ss-R:// 链接的含义

    1.问题 ss-R:// Mi41LmZ1Y2twcHBwcC50b2RheToyNDI4ODphdXRoX2FlczEyOF9tZDU6YWVzLTI1Ni1jdHI6dGxzMS4yX3RpY2t ...

  10. CodeForce Educational round Div2 C - Vasya and Robot

    http://codeforces.com/contest/1073/problem/C   题意:给你长度为n的字符串,每个字符为L, R, U, D.给你终点位置(x, y).你每次出发的起点为( ...