/*
* Copyright (c) 2004
* All rights reserved.
*
* 文件名称:PostOrder.c
* 文件标识:后序非递归遍历二叉树
* 摘 要:用栈模拟后序遍历二叉树
*
* 当前版本:1.0
* 作 者:Yu
* 完成日期:2004年8月8日
*
* 取代版本:1.0
* 原作者 :Yu
* 完成日期:2004年8月8日
*/
#include<stdio.h>
#include<stdlib.h>
#define STACK_INIT_SIZE 100//栈初始分配的空间数
#define STACKINCREAMENT 10//栈空间不够时增加的空间数
typedef char datatype;//二叉树结点信息类型
typedef struct BiTNode//二叉树结点类型
{
struct BiTNode *lchild,*rchild;
datatype data;
}BiTNode;
typedef enum{L,R} tagtype;//tag为L表示将访问该结点的左子树,tag为R表示将访问该结点的右子树
typedef struct stacknode//栈结点类型
{
BiTNode *ptr;//用于记录指向结点的指针
tagtype tag;//用于标记每个节点的LR值
}stacknode;
typedef struct stack//栈类型
{
stacknode *base;
stacknode *top;
int stacksize;
}sqstack;
sqstack *initstack()//建栈
{
sqstack *s;
if (!(s = (sqstack *)malloc(sizeof(sqstack))))exit(-1);
s->base = (stacknode *)malloc(STACK_INIT_SIZE*sizeof(stacknode));//初始化为栈分配STACK_INIT_SIZE个elemtype类型的空间
if (!s->base)//分配空间失败
{
exit(-2);
printf("栈空间分配失败!/n");
}
if (s->base)//分配空间成功
printf("栈空间分配成功!/n");
s->top = s->base;//初始化栈的头尾指针
s->stacksize = STACK_INIT_SIZE;
return s;
}
void push(sqstack *s,stacknode e)//压栈
{
if (s->top-s->base>=s->stacksize)//栈满
{
s->base = (stacknode *)realloc(s->base,(s->stacksize+STACKINCREAMENT)*sizeof(stacknode));//栈满时增加空间
if (!s->base)//增加分配空间失败
exit(-2);
s->stacksize += STACKINCREAMENT;
}
*(s->top) = e;
s->top++;
}
stacknode pop1(sqstack *s)//出栈1,返回的e为栈顶元素是一个地址
{
stacknode e;
if (s->top == s->base)exit(-1);//栈空时返回
s->top--;
e = *(s->top);
return e;
}
int stackempty(sqstack *s)//判断栈空,栈空返回1,否则返回0
{
if (s->base == s->top)return 1;
else return 0;
}
stacknode getop(sqstack *s)//获得栈顶元素
{
if (s->top == s->base)exit(-1);
return *(s->top-1);
}
BiTNode *CreateBiTree()//先序递归法建树
{
char x;
BiTNode *t;
scanf("%c",&x);
if (x == ' ')t = NULL;
else
{
if (!(t = (BiTNode *)malloc(sizeof(BiTNode))))exit(-1);
t->data = x;//建立节点
t->lchild = CreateBiTree();//建左子树
t->rchild = CreateBiTree();//建右子树
}
return t;
}
void PostOrder(BiTNode *t)
{
sqstack *s;
BiTNode *p;
stacknode x;
p = t;
s = initstack();
while (p || !stackempty(s))
{
while (p)//遍历左子树
{
x.ptr = p;
x.tag = L;
push(s,x);
p = p->lchild;
}
while (!stackempty(s) && (*(s->top-1)).tag == R)//判断tag是否为R。因为若是R,则表示从右子树返回
{
x = pop1(s);
p = x.ptr;
printf("%c",p->data); //tag为R,表示右子树访问完毕,故访问根结点
}
if (!stackempty(s))
{
(*(s->top-1)).tag = R; //从左子树返回,遍历右子树
p = (getop(s).ptr)->rchild;
}
}
}
void main()
{
BiTNode *t;
t=CreateBiTree();
PostOrder(t);
}