原理
见注释
//非递归后序遍历
void HOrder(BiTree T){
BiTree p = T, q = NULL;//q指向上次访问的节点
Stack S = CreateStack();
Push(S,p);//压入根节点
while(!IsEmpty(S)){
if(p&&p!=q){//如果当前节点不空并且没访问过,压入左孩子
Push(S,p);
p=p->lchild;
} else{
p = Pop(S);//出栈
if(!IsEmpty(S)){//根节点没被取出
if(p->rchild&&p->rchild!=q){//右孩子为真并且右孩子没被访问过,则重新压入父亲节点
Push(S,p);
p = p->rchild;//访问右孩子
} else{
printf("%c ",p->data);
q = p; //访问过之后标记
}
}
}
}
}
完整代码
以下还包括了堆栈非递归前序实现,中序则只需调整printf("%c ",T->data); 位置即可,因为他们访问节点的顺序是一样的。如下图
#include <stdlib.h>
#include <stdio.h>
typedef struct node
{
char data;
struct node *lchild,*rchild;
}BiNode,*BiTree;
void CreatBiTree(BiTree *T)
{
char a;
scanf("%c",&a);
if(a=='#')
*T=NULL;
else
{
*T=(BiTree)malloc(sizeof(BiNode));
(*T)->data=a;
CreatBiTree(&((*T)->lchild));
CreatBiTree(&((*T)->rchild));
}
}
//建立堆栈结构
typedef struct SNode{
BiTree Data;
struct SNode *next;
}SNode,*Stack;
//初始化堆栈
Stack CreateStack(){
Stack S;
S = (Stack)malloc(sizeof(struct SNode));
S->next = NULL;
return S;
}
//判断堆栈是否为空
int IsEmpty(Stack S){
return (S->next == NULL);
}
//压栈
void Push(Stack S,BiTree T){
Stack TmpCell;
TmpCell = (Stack)malloc(sizeof(Stack));
TmpCell->Data = T;
TmpCell->next = S->next;
S->next = TmpCell;
}
//出栈
BiTree Pop(Stack S){
Stack FirstCell;
BiTree TopElem;
if(IsEmpty(S)){
printf("堆栈空");
return 0;
} else {
FirstCell = S->next;
S->next = FirstCell->next;
TopElem = FirstCell->Data;
free(FirstCell);
return TopElem;
}
}
/*非递归前序遍历*/
void InOrderTraverasl(BiTree BT){
BiTree T = BT;
Stack S = CreateStack();
while(T||!IsEmpty(S)){
while(T){
Push(S,T);
T = T->lchild;
}
T = Pop(S);
printf("%c ",T->data);
T = T->rchild;
}
}
//非递归后序遍历
void HOrder(BiTree T){
BiTree p = T, q = NULL;//q指向上次访问的节点
Stack S = CreateStack();
Push(S,p);//压入根节点
while(!IsEmpty(S)){
if(p&&p!=q){//如果当前节点不空并且没访问过,压入左孩子
Push(S,p);
p=p->lchild;
} else{
p = Pop(S);//出栈
if(!IsEmpty(S)){//根节点没被取出
if(p->rchild&&p->rchild!=q){//右孩子为真并且右孩子没被访问过,则重新压入父亲节点
Push(S,p);
p = p->rchild;//访问右孩子
} else{
printf("%c ",p->data);
q = p; //访问过之后标记
}
}
}
}
}
int main() {
BiTree T;
CreatBiTree(&T);
InOrderTraverasl(T);
printf("\n");
HOrder(T);
return 0;
}