参考:https://blog.csdn.net/changshu1/article/details/47394227
刚开始做数据结构的题,这个题写了很久(躺了躺了
给定一个层数小于等于10的二叉树,输出对其后序遍历的节点名序列。
输入包括一行,为由空格分隔开的各节点,按照二叉树的分层遍历顺序给出,每个节点形式如X(Y,num),X表示该节点,Y表示父节点,num为0,1,2中的一个,0 表示根节点,1表示为父节点的左子节点,2表示为父节点的右子节点。输出为一行,为后序遍历的结果。
样例输入
A(0,0) B(A,1) C(A,2) D(B,1) E(B,2) F(C,1) G(D,1) H(D,2)
样例输出
G H D E B F C A
画了一张自己都懵(很)逼(难看)的图
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
/***
学号用int 描述,姓名用字符串描述采用的string,
于是我们使用的map形式如下:map<int , string> student;
对于map中的每个节点存储的是一对信息,包括一个键和一个值,
各个节点之间的键值不能重复。
***/
#include<stack>
using namespace std;
struct btNode{
char c;
btNode *left,*right;
btNode(char ch):c(ch),left(NULL),right(NULL){}
};
bool firstFlag;
/***
大致思路是:如果当前结点左右子树均为空,则可以访问当前结点,
或者左右子树不均为空(也就是前一个节点pre不为空),但是前一个访问的结点是当前结点的左孩子或
者右孩子,则也可以访问当前结点,如果前面两种情况均不满足
(即,当前结点的左右孩子不均为空,
并且前一个访问的结点不是当前结点左右孩子中的任意一个),
则若当前结点的右孩子不为空,将右孩子入栈,
若当前结点的左孩子不为空,将左孩子入栈。
***/
void postOrder(btNode * root){ //后序遍历结果
btNode *cur,*pre=NULL; //当前节点 前一个访问的节点
stack<btNode*> sk;
sk.push(root); //将根节点push进去 最后出来
while(!sk.empty()){ //如果不为空
cur=sk.top(); //当前节点
if((cur->left==NULL&&cur->right==NULL)||
(pre!=NULL&&(pre==cur->left||pre==cur->right)))
{
sk.pop();
if(firstFlag){
firstFlag=0; //第一个节点前不需要输出' '
}
else{
cout<<" ";
// putchar(' ');
}
cout<<cur->c;
//putchar(cur->c); //输出当前节点
}
/***
(即,当前结点的左右孩子不均为空,
并且前一个访问的结点不是当前结点左右孩子中的任意一个),
则若当前结点的右孩子不为空,将右孩子入栈,
若当前结点的左孩子不为空,将左孩子入栈。
***/
else{
if(cur->right){
sk.push(cur->right);
}
if(cur->left){
sk.push(cur->left);
}
}
pre=cur;
}
}
/***
样例输入
A(0,0) B(A,1) C(A,2) D(B,1) E(B,2) F(C,1) G(D,1) H(D,2)
样例输出
G H D E B F C A
***/
int main(){
freopen("test.txt","r",stdin);
//0 表示根节点,1表示为父节点的左子节点,2表示为父节点的右子节点。
char ch,fa,lr;//ch当前节点 fa父节点 lr:0 1 2 根节点 左 右
map<char,btNode*> mp;
btNode *root,*p,*q;
while(scanf("%c(%c,%c) ",&ch,&fa,&lr)==3){
if(fa=='0'){ //如果是根节点
root=new btNode(ch); //创建tree
mp[ch]=root; //根节点给mp.ch
}
else{ //如果不是根节点
p=mp[fa]; //父节点
q=new btNode(ch); //加入子树
mp[ch]=q;
if(lr=='1'){
p->left=q; //1表示q为父节点p的左子节点,
}
else{
p->right=q; //否则为右子节点
}
}
}
firstFlag=1; //flag 1
postOrder(root);
cout<<endl;
return 0;
}