问题描述
二叉树后序遍历的非递归算法:结点要入两次栈,出两次栈;为了区别同一个结点的两次出栈,设置标志flag,当结点进、出栈时,其标志flag也同时进、出栈。

设根指针为root,则可能有以下两种情况:
⑴ 若root!=NULL,则root及标志flag(置为1)入栈,遍历其左子树;
⑵ 若root=NULL,此时若栈空,则整个遍历结束;若栈不空,则表明栈顶结点的左子树或右子树已遍历完毕。若栈顶结点的标志flag=1,则表明栈顶结点的左子树已遍历完毕,将flag修改为2,并遍历栈顶结点的右子树;若栈顶结点的标志flag=2,则表明栈顶结点的右子树也遍历完毕,输出栈顶结点。
二叉树后序遍历的非递归算法伪代码如下
1. 栈s初始化;
2. 循环直到root为空且栈s为空
2.1 当root非空时循环
2.1.1将root连同标志flag=1入栈;
2.1.2 继续遍历root的左子树;
2.2 当栈s非空且栈顶元素的标志为2时,出栈并输出栈顶结点;
2.3 若栈非空,将栈顶元素的标志改为2,准备遍历栈顶结点的右子树;
实现代码
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define MaxSize 100
typedef int ElemType;
typedef int Status;
typedef struct BTNode{
ElemType data;
struct BTNode *lchild,*rchild;
}BTree;
typedef struct St{
struct BTNode* data[MaxSize];
int top;
}Stack;
//1.按先序次序生成二叉树
BTree* CreateT(){
BTree *BT;
scanf("%d",&ch);
if(ch==0)
BT=NULL;
else{
BT=(BTree*)malloc(sizeof(BTree));
if(!BT){exit(OVERFLOW);}
BT->data=ch;
BT->lchild=CreateT();
BT->rchild=CreateT();
}
return BT;
}
//2.后序遍历
Status PostOrder(BTree *BT) {
if(BT){
PostOrder(BT->lchild);
PostOrder(BT->rchild);
printf("%3d",BT->data);
return OK;
}
else return ERROR;
}
//3.后序遍历-非递归 Status PostOrder2(BTree *BT) {
Stack s,s2;
BTree *T;
int flag[MaxSize];
s.top=0;
T=BT;
while(s.top!=0||T){
while(T)
{
s.data[s.top++]=T;
flag[s.top-1]=0;
T=T->lchild;
}
while(s.top!=0&&flag[s.top-1]==1){
T=s.data[--s.top];
printf("%3d",T->data);
}
if(s.top!=0){
flag[s.top-1]=1;
T=s.data[s.top-1];
T=T->rchild;
}
else break;
}
return OK;
}
}
int main(){
BTree *BT;
BT=CreateT();
if(PostOrder(BT)){
}
if(PostOrder2(BT)){
printf("\n非递归后序遍历完成!\n");
}
}
运行结果

如有同校学弟学妹们见到这篇博客,切忌不要随意CV,请自主多动手多思考。
文章详细介绍了如何使用非递归方式实现二叉树的后序遍历,通过维护一个栈和使用标志flag来跟踪节点的状态。在遍历过程中,节点及其标志一起入栈,然后遍历左子树,当栈顶元素的标志为2时,表示左右子树都已遍历,出栈并输出节点。该方法避免了递归,适用于处理大型数据结构。

4445

被折叠的 条评论
为什么被折叠?



