树与二叉树——后序遍历二叉树的非递归算法

195 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

二叉树的后序遍历

算法思想:后序非递归遍历二叉树是先访问左子树,再访问右子树,最后访问根节点。 ①若根节点有左孩子,则左孩子以此入栈,直到左孩子为空,然后读取栈顶元素,若其右孩子不为空且未被访问过,则对右子树执行①。否则栈顶元素出栈并访问。

算法流程

  1. 定义一个p指针,指向当前访问的节点。
  2. 若p有左孩子则左孩子入栈,同时p只想左孩子,直到左孩子为空,将左孩子设置为被访问过;
  3. 依次读取栈顶元素,并判断其右孩子阶段是否为空,若为空则继续取出栈顶元素,若不为空切未被访问过,则对右子树进行1的操作;
  4. 栈为空,且树中的节点都被访问过,程序结束。

例:

image.png 对上图进行后序遍历。

代码:

#include <bits/stdc++.h>
using namespace std;

typedef struct TreeNode{
    char data;
    struct TreeNode *lchild,*rchild;
    int tag;
}TreeNode ,*Tree;


// 递归构造二叉树
void createTree(Tree &t){
    char ch;
    ch = getchar();
    if (ch=='#') t=NULL;
    else{
        t = (TreeNode *)malloc(sizeof(TreeNode));
        t->data = ch;
        t->tag = 0;
        t->lchild =NULL;
        t->rchild = NULL;
        createTree(t->lchild);
        createTree(t->rchild);
         

    }
}


void back(Tree t){
    struct TreeNode *stack[30];
    int top = -1;
    TreeNode *p = t;
    TreeNode *x;
//若p存在或者栈不为空则可继续进行
    while(p||top!=-1){
    
	//若p存在则入栈并将p指向左孩子结点
        if(p){
            top++;
            stack[top]=p;
            p=p->lchild;
        }
	//p不存在,则将p指向栈顶元素。
        else{
            p=stack[top];
//判断是否有右孩子并且有没有被访问。
            if(p->rchild&&p->rchild->tag == 0){
                p=p->rchild;

            }else{
                p=stack[top];
                top--;
                cout<<p->data<<" ";
                p->tag = 1;
                p=NULL;
            }



        }

    }
}



int main(){
    Tree t;
    createTree(t);
    back(t);
    return 0;
}
// ABD##E##C##