实现思路:从根节点开始遍历二叉树,不为空时将节点压入栈中,直到最后一个非空节点。然后判断此节点的是否有右孩子,如果右孩子为空,那么输出节点数据。否则判断右孩子是否是之前遍历过的(用pre指针记录之前遍历过多的节点指针),如果是那么输出此节点,否则右孩子压入栈中。
具体代码:
#include <stdio.h>
#include <stdlib.h>
struct node{
char data;
node *lchild;
node *rchild;
};
void post_order(node *root){
node *stack[100];
int top = 0;
node *pre = NULL;
while (root!=NULL||top!=0)
{
while (root!=NULL)//入栈
{
stack[top++] = root;
root = root->lchild;
}
if (top!=0)//栈中的元素不为空时 进行处理
{
root = stack[top-1];//取出栈顶元素
if (root->rchild==NULL||root->rchild==pre)
{//右节点为空 或者已经被访问过了 出栈
printf("->%c ",root->data);
top--;
pre = root;
root = NULL;//为了防止再次入栈 将他设为空
}
else
{
root = root->rchild;
}
}//if
}//while
}
有几点要注意的地方:
节点的数据输出之后才能出栈,即top--。
输出并处理这些节点的条件是栈不为空。
输出节点的数据之后,节点要置空,否则会再次将此节点压入栈中。
非递归的先序遍历
主要思路就是让根节点先入栈,然后出栈,访问根节点。然后让根节点的右子树入栈,左子树入栈,再按照上述方式来遍历,知道栈为空。
void pre_order(node *root){
node *stack[100];
int top = 0;
if (root == NULL)
return;
stack[top++] = root;
while (top!=0)
{
printf("->%c ",stack[--top]->data);
if (root->rchild != NULL)
stack[top++] = root->rchild;
if (root->lchild != NULL)
stack[top++] = root->lchild;
}
}
非递归的中序遍历
中序遍历的思想是将根节点的左子树不断的压栈,直到最后一个不为空的节点,输出此节点,然后将root设置为右子树,返回while循环重复以上操作操作。
void in_order(node *root){
node *stack[100];
int top = 0;
while (root != NULL||top!=0)
{
while(root!=NULL)
{
stack[top++] = root;
root = root->lchild;//左子树不断的压栈
}
//和后序不同 先输出根节点
root = stack[--top];
printf("->%c ",root->data);
root = root->rchild;
}
}