什么也不说直接写代码
#include<stack>
using namespace std;
typedef int DType;
typedef struct _BNode
{
DType data;
_BNode *left, *right;
}BNode;
typedef stack<BNode*> BNodeStack;
typedef void (*bVisit)(DType data);
void NoRecursionPostTraverse(BNode* bTree, bVisit visit)
{
BNodeStack visitStack;
if (bTree)
{
visitStack.push(bTree);
}
BNode* preNode = NULL;
while (!visitStack.empty())
{
BNode* temp = visitStack.top();
if ((temp->left == NULL && temp->right == NULL) ||
(temp->right && preNode == temp->right) ||
(temp->left&&preNode == temp->left))
{
visit(temp->data);
preNode = temp;
visitStack.pop();
}
else
{
if (temp->right)
{
visitStack.push(temp->right);
}
if (temp->left)
{
visitStack.push(temp->left);
}
}
}
}
void OutPut(DType data)
{
printf("%2d\t", data);
}
int _tmain(int argc, _TCHAR* argv[])
{
BNode root;
BNode left1;
BNode right1;
BNode left11;
root.data = 0;
root.left = &left1;
root.right = &right1;
left1.data = 10;
left1.left = &left11;
left1.right = NULL;
left11.data = 100;
left11.left = NULL;
left11.right = NULL;
right1.data = 20;
right1.left = NULL;
right1.right = NULL;
NoRecursionPostTraverse(&root, OutPut);
return 0;
}
执行结果
复习数据结构查了一下网,说二叉树遍历非递归后序遍历是最难理解的,试着写了写,知识就是慢点练习而已。
总体思想是 先入栈右子树,再入栈左子树,达到先后顺序。这里记录上一个遍历的结点是出栈判断用的,如果没有子树直接调用visit,但是有子树就需要遍历完子树才能出栈,如何算遍历完呢,后序遍历的特殊性,如果有右子树,就是右子树,如果没有就是左子树了。