#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define STACK_INIT_SIZE 100//栈存储空间初始分配量
#define STACKINCREMENT 10//栈存储空间分配增量
#define MAXSIZE 100 //最大队列长度
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;//定义Status函数类型为int
typedef char TElemType;//定义二叉树TElemType元素类型为char
typedef struct BiTNode1//二叉树二叉链表结构
{
TElemType data;
struct BiTNode1 *lchild,*rchild;//左右孩子指针
int weight; //标记是否遍历右孩子
} BiTNode1, *BiTree1;
typedef BiTree1 SElemType;//定义栈元素类型为二叉树二叉链表结点
typedef struct
{
SElemType *base; //栈的起始地址,当栈为空时,base的值为0
SElemType *top; //栈顶指针,始终指向栈顶元素的下一位置
int stacksize; //当前分配的栈的存储空间大小,以元素为单位
} SqStack; //SqStack顺序栈类型
typedef struct BiTNode2//二叉树三叉链表结构
{
TElemType data;
struct BiTNode2 *parent,*lchild,*rchild;//双亲及左右孩子指针
int weight;//标记是否遍历输出过该结点
} BiTNode2, *BiTree2;
typedef BiTree2 QElemType;//定义队列元素类型为二叉树三叉链表结点
typedef struct
{
QElemType *base; //初始化动态分配存储空间
int front; //头指针,若队列不空,指向队列元素
int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue; //SqQueue循环队列类型
char str[16]="abc000de0f00g00";//二叉树先序序列
int cnt1,cnt2;//二叉树先序序列计数器
Status InitStack(SqStack *S);//初始化栈S
Status Push(SqStack *S,SElemType e);//将元素e放入栈顶
Status Pop(SqStack *S,SElemType *e);//移走栈顶的元素,同时并由e返回该元素的值
Status StackEmpty(SqStack S); //判断栈是否为空
Status GetTop(SqStack S, SElemType *e);//获取栈顶的元素,但不从栈中移走
Status DestoryStack(SqStack *S);//销毁栈S,S不再存在
Status InitQueue(SqQueue *Q);//初始化队列Q
Status EnQueue(SqQueue *Q,QElemType e); //将元素e放入队尾
Status DeQueue(SqQueue *Q,QElemType *e);//移走队头元素,由e返回该元素的值
Status QueueEmpty(SqQueue Q);//判断队列是否为空
BiTree1 CreateBiTree1(BiTree1 T);//构造二叉链表表示的二叉树T1
BiTree2 CreateBiTree2(BiTree2 T);//构造三叉链表表示的二叉树T2
Status BiTreeThreading(BiTree2 T);//构造三叉链表二叉树双亲指针
Status PreorderTraverse(BiTree1 T, Status(*Visit)(TElemType e));//前序遍历二叉树T的非递归算法
Status InorderTraverse(BiTree1 T, Status(*Visit)(TElemType e));//中序遍历二叉树T的非递归算法
Status PostorderTraverse1(BiTree1 T, Status(*Visit)(TElemType e));//后序遍历二叉树T的非递归算法
Status PostorderTraverse2(BiTree2 T, Status(*Visit)(TElemType e));//无栈非递归后序遍历二叉树T
Status PrintfElement(TElemType e);//输出树元素
BiTree1 T1;//定义全局变量生成二叉链表根结点
BiTree2 T2;//定义全局变量生成三叉链表根结点
int main()
{
printf("二叉树按先序输入的结点序列为:\nabc000de0f00g00");
printf("\n\n二叉树二叉链表表示:");
T1=CreateBiTree1(T1); //构造二叉链表表示的二叉树T1
printf("\n先序遍历(非递归):");
PreorderTraverse(T1,PrintfElement); //前序遍历二叉树T1的非递归算法
printf("\n中序遍历(非递归):");
InorderTraverse(T1,PrintfElement); //中序遍历二叉树T1的非递归算法
printf("\n后序遍历(非递归):");
PostorderTraverse1(T1,PrintfElement); //后序遍历二叉树T的非递归算法
printf("\n\n二叉树三叉链表表示:");
T2=CreateBiTree2(T2); //构造三叉链表表示的二叉树T2
BiTreeThreading(T2); //构造三叉链表二叉树双亲指针
printf("\n后序遍历(无栈非递归):");
PostorderTraverse2(T2,PrintfElement); //无栈非递归后序遍历二叉树T2
return 0;
}
Status InitStack(SqStack *S)//初始化栈S
{
/* 构造一个空栈S */
S->base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S->base) return OVERFLOW;/*存储分配失败*/
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;
return OK;
}/*InitStack*/
Status Push(SqStack *S,SElemType e) //将元素e放入栈顶
{
/* 插入元素e为新的栈顶元素 */
if(S->top-S->base>=S->stacksize)/* 栈已满,追加空间*/
{
S->base=(SElemType*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S->base) return OVERFLOW;/*存储分配失败*/
S->top=S->base+S->stacksize;/*求新空间的栈顶指针*/
S->stacksize+=STACKINCREMENT;/*新空间的容量*/
}
*S->top=e;/*在栈顶插入元素x*/
S->top++;/*修改栈顶指针*/
return OK;
}/*Push*/
Status Pop(SqStack *S,SElemType *e) //移走栈顶的元素,同时并由e返回该元素的值
{
/*若栈不空,则删除S的栈顶元素,并用x返回其值,并返回OK,否则返回ERROR*/
if(S->top==S->base) return ERROR;/*栈为空,返回ERROR*/
S->top--;/*修改栈顶指针,使其指向栈顶元素*/
*e=*S->top;
return OK;
}
Status StackEmpty(SqStack S) //判断栈是否为空
{
if(S.base==S.top) return TRUE; //若栈为空,返回TRUE
else return FALSE; //否则返回FALSE
}
Status GetTop(SqStack S, SElemType *e)//获取栈顶的元素,但不从栈中移走
{
// 若栈不空,则用e返回S的栈顶元素,并返回OK;
//否则返回ERROR
if (S.top==S.base) return ERROR; //若栈为空
*e =*(S.top-1);
return OK;
}//GetTop
Status DestoryStack(SqStack *S)//销毁栈S,S不再存在
{
//释放栈空间,栈顶栈底指针置为NULL,长度置为0
free(S->base);
S->base=S->top=NULL;
S->stacksize=0;
return OK;
}
Status InitQueue(SqQueue *Q)//初始化队列Q
{
//构造一个空队列Q
Q->base=(QElemType* )malloc(MAXSIZE*sizeof(QElemType));
if (!Q->base) exit (OVERFLOW);//存储分配失败
Q->front = Q->rear = 0;
return OK;
}
Status EnQueue(SqQueue *Q,QElemType e) //将元素e放入队尾
{
//插入元素e为Q的新的队尾元素
if ((Q->rear+1) % MAXSIZE == Q->front) return ERROR;//队列满
Q->base[Q->rear] = e;
Q->rear = (Q->rear+1) % MAXSIZE;
return OK;
}
Status DeQueue(SqQueue *Q,QElemType *e)//移走队头元素,由e返回该元素的值
{
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;
//否则返回ERROR
if (Q->front == Q->rear) return ERROR;
*e=Q->base[Q->front];
Q->front = (Q->front+1) % MAXSIZE;
return OK;
}
Status QueueEmpty(SqQueue Q)//判断队列是否为空
{
if(Q.front==Q.rear) return OK;
return ERROR;
}
BiTree1 CreateBiTree1(BiTree1 T)//构造二叉链表表示的二叉树T1
{
char ch=str[cnt1++];
if(ch=='0') T=NULL;
else
{
if(!(T=(BiTree1)malloc(sizeof(BiTNode1)))) exit(OVERFLOW); /*申请一个结点空间*/
T->data=ch;//生成根结点
T->lchild=CreateBiTree1(T); //构造左子树
T->rchild=CreateBiTree1(T);//构造右子树
}
return T; /*返回指向根结点的指针*/
}/* CreateBiTree1*/
BiTree2 CreateBiTree2(BiTree2 T)//构造三叉链表表示的二叉树T2
{
char ch=str[cnt2++];
if(ch=='0') T=NULL;
else
{
if(!(T=(BiTree2)malloc(sizeof(BiTNode2)))) exit(OVERFLOW); /*申请一个结点空间*/
T->data=ch;//生成根结点
T->weight=0;//标记清零
T->lchild=CreateBiTree2(T); //构造左子树
T->rchild=CreateBiTree2(T);//构造右子树
}
return T; /*返回指向根结点的指针*/
}/* CreateBiTree2*/
Status BiTreeThreading(BiTree2 T)//构造三叉链表二叉树双亲指针
{
SqQueue q;
QElemType e;
if (T) /* 非空树 */
{
T->parent = NULL; /* 根结点的双亲为"空" */
InitQueue(&q); /* 初始化队列 */
EnQueue(&q, T); /* 根指针入队 */
while (!QueueEmpty(q)) /* 队不空 */
{
DeQueue(&q, &e); /* 出队,队列元素赋给e */
if (e->lchild) /* 有左孩子 */
{
e->lchild->parent =e; /* 给左孩子的双亲指针赋值 */
EnQueue(&q, e->lchild); /* 左孩子入队 */
}
if (e->rchild) /* 有右孩子 */
{
e->rchild->parent = e; /* 给右孩子的双亲指针赋值 */
EnQueue(&q, e->rchild); /* 右孩子入队 */
}
}
}
return OK;
}
Status PrintfElement(TElemType e)//输出树元素
{
printf("%c",e);
return OK;
}
Status PreorderTraverse(BiTree1 T, Status(*Visit)(TElemType e)) //前序遍历二叉树T的非递归算法
{
SElemType p;/*构造栈元素*/
SqStack S;
InitStack(&S);
p=T;
while(p||!StackEmpty(S))
{
if(p)
{
if(!Visit(p->data)) return ERROR;
Push(&S, p);
p=p->lchild;
} //访问根结点,根指针进栈,遍历左子树
else //根指针退栈,遍历右子树;
{
Pop(&S, &p);
p=p->rchild;
}
}
return OK;
}
Status InorderTraverse(BiTree1 T, Status(*Visit)(TElemType e)) //中序遍历二叉树T的非递归算法
{
//采用二叉链表存储结构,visit是对数据元素操作的应用函数。
//中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit.
SElemType p;/*构造栈元素*/
SqStack S;/*构造顺序栈*/
InitStack(&S);
p=T;
while(p||!StackEmpty(S))
{
if(p)
{
Push(&S,p); //根指针进栈,遍历左子树
p=p->lchild;
}
else //根指针退栈,访问根结点,遍历右子树;
{
Pop(&S,&p);
if(!Visit(p->data)) return ERROR;
p=p->rchild;
}
}
return OK;
}
Status PostorderTraverse1(BiTree1 T, Status(*Visit)(TElemType e))//后序遍历二叉树T的非递归算法
{
//采用二叉链表存储结构,visit是对数据元素操作的应用函数。
//中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit.
SqStack S;
SElemType p;/*构造栈元素*/
InitStack(&S);
p=T;
p->weight=0;
while(p||!StackEmpty(S))
{
if(p)
{
Push(&S,p); //根指针进栈,遍历左子树
p->weight=0;//当前结点未寻找过右子树
p=p->lchild;
}
else
{
GetTop(S,&p);
if(p->weight==0) //遍历右子树
{
p->weight=1;//标记已经寻找过右子树
p=p->rchild;
}
else //根指针退栈,访问根结点,返回上一层
{
Pop(&S,&p);
if(!Visit(p->data)) return ERROR;
p=NULL;
}
} //else
} //while
return OK;
}
Status PostorderTraverse2(BiTree2 T, Status(*Visit)(TElemType e))//无栈非递归后序遍历二叉树T
{
while(T)
{
while(T->lchild && !T->lchild->weight)//如果左子树未访问,沿着树向左下方移动,
{
//直到不能再走为止
T=T->lchild;
}
if(T->rchild && !T->rchild->weight)//如果右子树未访问,更新指针访问右子树
{
T=T->rchild;
}
else//左子树已访问或左子树不存在且右子树已访问或右子树不存在
{
if(!Visit(T->data)) return ERROR;//输出结点信息,标记已经访问
T->weight=1;
T=T->parent; //指针返回上一层指向双亲结点
}
}
return OK;
}