二叉树后序遍历非递归算法(详解)

前序和中序都比较简单 后序我按自己的理解好好说一下吧,基本思路是利用堆栈将递归转化为循环
首先定义节点结构

struct BTNode {
    int val;
    bool visR;
    bool visL;
    BTNode *LeftChild, *RightChild;
    BTNode() :val(0),LeftChild(NULL),RightChild(NULL),visR(false),visL(false){}
};

我为了方便用了构造函数(visL和visR表示当前节点有没有遍历过左右子树)
1、从根节点开始,遇到一个节点就将其压栈,将visL置为T(因为后序遍历第二次访问元素不出栈 所以防止二次访问左子树),并去遍历他的左子树- - ->这是第一次访问节点
2、当左子树遍历结束,即p==NULL,此时令指针指向栈顶节点但不出栈(即当前所访问元素)- - ->这是第二次访问节 点, 若未访问过左子树 p=p->RightChild,否则输出p,并将其出栈(此时该节点已遍历过左子树右子树)
下面是程序 带测试实例(arrayStack是我自己做的栈 可换为STL的stack)

#pragma warning(disable:4996)
#include <iostream>
#include "arrayStack.h"
using namespace std;
struct BTNode {
    int val;
    bool visR;
    bool visL;
    BTNode *LeftChild, *RightChild;
    BTNode() :val(0),LeftChild(NULL),RightChild(NULL),visR(false),visL(false){}
};
arrayStack<BTNode *>s;
int main() {
    BTNode *p1 = new BTNode;
    p1->val = 0;
    BTNode *p2 = new BTNode;
    p2->val = 1;
    BTNode *p3 = new BTNode;
    p3->val = 2;
    BTNode *p4 = new BTNode;
    p4->val = 3;
    BTNode *p5 = new BTNode;
    p5->val = 4;
    p1->LeftChild = p2;
    p1->RightChild = p3;
    p3->LeftChild = p4;
    p3->RightChild = p5;
    BTNode *focus = p1;
    while (focus || !s.empty()) {
        while (focus) {
            if(!focus->visL){
                focus->visL = true;
                s.push(focus);
            }
            focus = focus->LeftChild;
        }
        focus = s.top();
        if (!focus->visR) {
            focus->visR = true;
            focus = focus->RightChild;
        }
        else {
            cout << focus->val << " ";
            s.pop();
            if (!s.empty())focus = s.top();
            else focus = NULL;
        }
    }
    cout << endl;
}

猜你喜欢

转载自blog.csdn.net/Leslie5205912/article/details/81560906
今日推荐