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