后序遍历二叉树
递归的后序遍历二叉树还是和之前一样,调整一下输出语句就可以。非递归有两种方式,一种是规规矩矩的类似中序的迭代,另一种是通过倒序输出镜像前序的序列来得到后序序列。
依旧是那棵老树:
/*------------
树的形状:
a
b c
d e f
--------------*/
递归:
//递归
void PostOrder(Tree& t){
if(t == NULL) return;
PostOrder(t->left);
PostOrder(t->right);
cout<<t->val<<" ";
}
非递归:
//非递归
/*中序非递归的代码稍加修改*/
void PostOrderTraversal(Tree& t){
/*与中序遍历的差别在于从左孩子走到根节点后不是急着输出
根节点,而是再进入右结点,之后再返回,这样根节点会被访问到两次,
设置指向上一个被访问结点的标志pre,限制它只能访问一次右孩子。*/
stack<TreeNode*> s;
TreeNode* cur = t;
TreeNode* pre = NULL;
//左-中-右
while(cur != NULL || !s.empty()){
while(cur != NULL){
s.push(cur);
cur=cur->left;
}
cur = s.top();//此时查看的是最左边的叶子结点
if(cur->right == NULL || cur->right == pre){
//如果该结点的右孩子为空或者被访问过,该访问根节点
cout<<cur->val<<" ";
s.pop();//根节点被访问过,应该出栈
pre = cur;//更新被访问过的结点
cur = NULL;//已经被访问过,避免上方while循环再次进栈
}
//右孩子非空,且未被访问过
else cur = cur->right;//去右子树重新执行上述过程
}
}
代码如下:
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
typedef struct node{
char val;
struct node* left;
struct node* right;
}TreeNode,*Tree;
//递归
void PostOrder(Tree& t){
if(t == NULL) return;
PostOrder(t->left);
PostOrder(t->right);
cout<<t->val<<" ";
}
//非递归
/*中序非递归的代码稍加修改*/
void PostOrderTraversal(Tree& t){
/*与中序遍历的差别在于从左孩子走到根节点后不是急着输出
根节点,而是再进入右结点,之后再返回,这样根节点会被访问到两次,
设置指向上一个被访问结点的标志pre,限制它只能访问一次右孩子。*/
stack<TreeNode*> s;
TreeNode* cur = t;
TreeNode* pre = NULL;
//左-中-右
while(cur != NULL || !s.empty()){
while(cur != NULL){
s.push(cur);
cur=cur->left;
}
cur = s.top();//此时查看的是最左边的叶子结点
if(cur->right == NULL || cur->right == pre){
//如果该结点的右孩子为空或者被访问过,该访问根节点
cout<<cur->val<<" ";
s.pop();//根节点被访问过,应该出栈
pre = cur;//更新被访问过的结点
cur = NULL;//已经被访问过,避免上方while循环再次进栈
}
//右孩子非空,且未被访问过
else cur = cur->right;//去右子树重新执行上述过程
}
}
//非递归
/*前序非递归的代码稍加修改*/
void postOrderTraversal(Tree& t){
/*前序遍历顺序:中->左->右,
前序遍历左右颠倒:中->右->左,变成了前序遍历的镜像,
整个顺序再颠倒:右->左->中,得到了后序遍历的序列。 */
if(t == NULL) return;
stack<TreeNode*> s;
stack<char> res; //用一个栈来倒序输出结果
s.push(t); //根结点入栈
while(!s.empty()){
TreeNode* p = s.top();
res.push(p->val);
s.pop();
//对前序的入栈顺序做了调整,使它以镜像前序的方式遍历
if(p->left != NULL)
s.push(p->left);
if(p->right != NULL)
s.push(p->right);
}
//倒序输出
while(!res.empty()){
cout<<res.top()<<" ";
res.pop();
}
}
void CreateTree(Tree& t){
char x;
cin>>x;
if(x == '#') t = NULL;
else{
t = new TreeNode;
t->val = x;
CreateTree(t->left);
CreateTree(t->right);
}
}
void levelOrder(Tree& t) {
if(t == NULL) return;
queue<TreeNode*> q;
q.push(t);
while(!q.empty()){
int n = q.size();
for(int i = 0;i<n;i++){
TreeNode* s = q.front();
cout<<s->val<<" ";
q.pop();
if(s->left) q.push(s->left);
if(s->right) q.push(s->right);
}
cout<<endl;
}
}
int main(){
Tree t;
CreateTree(t);
/*
a b d # # e # # c f # # #
*/
levelOrder(t);
cout<<endl<<"递归:"<<endl;
PostOrder(t);
cout<<endl<<"非递归1:"<<endl;
PostOrderTraversal(t);
cout<<endl<<"非递归2:"<<endl;
postOrderTraversal(t);
}
运行结果: