1086 Tree Traversals Again
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:
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
题意:
采用非递归的方式来确定一颗二叉树,然后将这颗二叉树按照后序遍历的方式来输出。
思路:
这道题用到的理论知识就是通过一棵二叉树的先序遍历和中序遍历来构建这棵树,当然前提是你能够看出来进栈的序列是先序遍历的结果,出栈的序列是中序遍历的结果。构建树的代码(递归):
Node CreateTree(int left, int right){
if(left > right) return NULL;
int root = preOrder[cur];
cur++;
int rootIndex = findRootIndex(root);
Node T = new TreeNode();
T->num = root;
if(left != right){
T->left = CreateTree(left,rootIndex-1);
T->right = CreateTree(rootIndex+1,right);
}
return T;
}
Code:
#include<iostream>
#include<queue>
#include<stack> using namespace std; typedef struct Node *node;
struct Node {
int value;
node leftSon;
node rightSon;
node father;
Node():value(), leftSon(), rightSon(), father(){}
}; void postOrder(node h) {
if (h != NULL) {
postOrder(h->leftSon);
postOrder(h->rightSon);
cout << h->value << " ";
}
} int main() {
int n;
cin >> n;
getchar();
string str, op, num;
int pos;
queue<string> q;
stack<int> s;
stack<string> leftOrRight;
for (int i = 0; i < n*2; ++i) {
getline(cin, str);
if (str[1] == 'u') {
pos = str.find(' ');
op = str.substr(0, pos);
num = str.substr(pos+1);
q.push(op);
q.push(num);
} else {
q.push(str);
}
} node head = new Node();
node prt = head;
while (!q.empty()) {
if (q.front() == "Push") {
q.pop();
int value = stoi(q.front());
s.push(value);
q.pop();
node temp = new Node();
if (prt->leftSon) {
leftOrRight.push("right");
prt->rightSon = temp;
temp->father = prt;
} else {
leftOrRight.push("left");
prt->leftSon = temp;
temp->father = prt;
}
prt = temp;
} else {
q.pop();
if (leftOrRight.top() == "left") prt = prt->father;
prt->value = s.top();
if (leftOrRight.top() == "right") prt = prt->father;
s.pop();
leftOrRight.pop();
}
}
postOrder(prt);
return 0;
}
以上是我写的代码,因为没有注意到题目中暗含着两种遍历,所以写的代码也很乱,当然也是错误的。
以下的代码来自:https://blog.csdn.net/xyt8023y/article/details/47443489
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <sstream>
#include <stack> using namespace std; int N,cur;
vector<int> preOrder;
vector<int> inOrder; typedef struct TreeNode *Node;
struct TreeNode{
int num;
Node left,right; TreeNode(){
left = NULL;
right = NULL;
} }; int findRootIndex(int rootNum){ for(int i = 0;i < N; i++){
if(inOrder[i] == rootNum){
return i;
}
}
return -1; } Node CreateTree(int left, int right){
if(left > right) return NULL;
int root = preOrder[cur];
cur++;
int rootIndex = findRootIndex(root);
Node T = new TreeNode();
T->num = root;
if(left != right){
T->left = CreateTree(left,rootIndex-1);
T->right = CreateTree(rootIndex+1,right);
}
return T;
} bool firstOutPut = true;
void PostOrder(Node T){
if(!T) return;
PostOrder(T->left);
PostOrder(T->right);
if(firstOutPut){
printf("%d",T->num);
firstOutPut = false;
}else{
printf(" %d",T->num);
}
} int main()
{
stringstream ss;
string Nstr;
getline(cin,Nstr);
ss << Nstr;
ss >> N;
ss.clear();
string input;
stack<int> stk;
int value;
for(int i = 0; i < N * 2; i++){
getline(cin,input);
if(input[1] == 'u'){
string num = input.substr(5);
ss << num;
ss >> value;
ss.clear();
stk.push(value);
preOrder.push_back(value);
}else{
value = stk.top();
stk.pop();
inOrder.push_back(value);
}
}
Node T = CreateTree(0,N-1);
PostOrder(T);
return 0;
}
值得注意的是cur并没有赋初值,测试发现他的初值默认为0.
1086 Tree Traversals Again的更多相关文章
- PAT 1086 Tree Traversals Again
PAT 1086 Tree Traversals Again 题目: An inorder binary tree traversal can be implemented in a non-recu ...
- PAT 1086 Tree Traversals Again[中序转后序][难]
1086 Tree Traversals Again(25 分) An inorder binary tree traversal can be implemented in a non-recurs ...
- PAT 甲级 1086 Tree Traversals Again (25分)(先序中序链表建树,求后序)***重点复习
1086 Tree Traversals Again (25分) An inorder binary tree traversal can be implemented in a non-recu ...
- 1086 Tree Traversals Again——PAT甲级真题
1086 Tree Traversals Again An inorder binary tree traversal can be implemented in a non-recursive wa ...
- 1086. Tree Traversals Again (25)
题目如下: An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For e ...
- PAT 甲级 1086 Tree Traversals Again
https://pintia.cn/problem-sets/994805342720868352/problems/994805380754817024 An inorder binary tree ...
- PAT Advanced 1086 Tree Traversals Again (25) [树的遍历]
题目 An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For exam ...
- 1086. Tree Traversals Again (25)-树的遍历
题意:用栈的push.pop操作给出一棵二叉树的中序遍历顺序,求这棵二叉树的后序遍历. 需要一个堆结构s,一个child变量(表示该节点是其父亲节点的左孩子还是右孩子),父亲节点fa对于push v操 ...
- 1086 Tree Traversals Again (25 分)(二叉树的遍历)
用栈来模拟一棵二叉树的先序遍历和中序遍历过程,求这棵二叉树的后序遍历 由题棵知道:push是先序遍历 pop是中序遍历 #include<bits/stdc++.h> using name ...
随机推荐
- WPF权限控制框架——【4】抛砖引玉
写第一篇"权限控制框架"系列博客是在2021-01-29,在这不到一个月的时间里,收集自己零碎的时间,竟然写出了一个"麻雀虽小,五脏俱全"的权限控制框架:对于一 ...
- C#日志使用
本文参考链接 日志框架 框架选择:NLog 安装方法,Nuget命令行:Install-Package NLog 常用规则 尽量不要在循环中打印日志. 应输出错误的堆栈信息:e.Message仅为异常 ...
- Kubernetes-3.安装
docker version:19.03.14 kubernetes version:1.19.4 本文介绍使用kubeadm安装Kubernetes集群的简单过程. 目录 使用kubeadm安装k8 ...
- matplotlib工具栏源码探析三(添加、删除自定义工具项)
转: matplotlib工具栏源码探析三(添加.删除自定义工具项) matplotlib工具栏源码探析二(添加.删除内置工具项)探讨了工具栏内置工具项的管理,除了内置工具项,很多场景中需要自定义工具 ...
- pytorch(02)tensor的概念以及创建
二.张量的简介与创建 2.1张量的概念 张量的概念:Tensor 张量是一个多维数组,它是标量.向量.矩阵的高维拓展 Tensor与Variable Variable是torch.autograd(t ...
- 快速查找未打补丁的exp
在windows DOS窗口下输入以下内容,输出为未打的补丁信息列表 systeminfo>vul.txt&(for %i in (KB977165 KB2160329 KB250366 ...
- mongodb 聚合(aggregate)
MongoDB中文手册|官方文档中文版 https://docs.mongoing.com/ 聚合操作处理数据记录和 return 计算结果.聚合操作将来自多个文档的值组合在一起,并且可以对分组数 ...
- CNN结构演变总结(三)设计原则
CNN结构演变总结(一)经典模型 CNN结构演变总结(二)轻量化模型 前言: 前两篇对一些经典模型和轻量化模型关于结构设计方面的一些创新进行了总结,在本文将对前面的一些结构设计的原则,作用进行总结. ...
- WPF 基础 - Binding 对数据的转换和校验
1. Binding 对数据的转换和校验 Binding 中,有检验和转换关卡. 1.1 数据校验 源码: namespace System.Windows.Data { public class B ...
- Python中异步协程的使用方法介绍
1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后 ...