如有错误,欢迎大家指出来
定义的栈,队列,二叉树结构体
typedef struct node{
Bitree tri;
struct node *next;
}lnode;
typedef struct{
lnode *front,*rear;
}linkqueue;//链队列
typedef struct liknode{
Bitree tre;
struct liknode *next;
}stacknode;
typedef struct stac{
stacknode *top;
}linkstack;//链栈
typedef struct bi{
int num;
struct bi *lchild,*rchild;
}Binode,*Bitree;//二叉树节点
#include"tree.h"
#include<stdio.h>
#include"queue.h"
#include<stdlib.h>
#include"stack.h"
void visit(Bitree p)
{
printf("%d ",p->num);
}
Bitree create(Bitree q)
{
int n;
printf("input :");
scanf("%d",&n);
if(n==-1) q=NULL;//输入为-1时,表示节点为空,否则开辟空间,增加节点
else {
q=(Bitree)malloc(sizeof(Binode));
q->num=n;
q->lchild=create(q->lchild);
q->rchild=create(q->rchild);//利用递归先序遍历创建法!
}
return q;
}
void preorder(Bitree p)//递归先序
{
if(p!=NULL)
{
printf("%d ",p->num);
preorder( p->lchild);
preorder(p->rchild);
}
}
void inorder(Bitree p)//递归中序
{
if(p!=NULL){
inorder(p->lchild);
printf("%d ",p->num);
inorder(p->rchild);
}
}
void postorder(Bitree p)//递归后序
{
if(p!=NULL)
{
inorder(p->lchild);
inorder(p->rchild);
printf("%d ",p->num);
}
}
void levelorder(Bitree p)//队列实现层次遍历
{
linkqueue *q;
q=(linkqueue *)malloc(sizeof(linkqueue));
iniqueue(q);
Bitree t=p;
enqueue(q,t);
while(!quempty(q))
{ t=dequeue(q);
printf("%d ",t->num);
if(t->lchild!=NULL) enqueue(q,t->lchild);
if(t->rchild!=NULL) enqueue(q,t->rchild);
}//首先,根节点进队,非空,输出根节点,发现根节点有左右节点,把他们入队,又回到while,非空,
} //根节点的左孩子出队,发现左孩子还有孩子,将之入队,根节点的右孩子出队,发现它有孩子就把孩子入队
//依次下去直到queempty退出while
void inordertraver(Bitree p)//非递归中序.栈实现
{
linkstack *r;
r=(linkstack*)malloc(sizeof(linkstack));
inistack(r);//构建好链栈r
Bitree t;
t=p;//p作为指向树的根节点指针,不要改变,声明一个指针t=p来实现遍历
while(t||!stackempty(r))//t非空或者栈非空
{
if(t) {push(r,t);t=t->lchild;}//若t不为空,入栈,
else { //t为空,此时栈顶元素为t父节点,出栈,且使t指向父节点
t=pop(r); visit(t);
t=t->rchild;//t指向它的右孩子t=t->rchild
}
}//若右孩子t为空,栈不为空,再次进入while,pop出最近进入的一个节点,即此时t的父节点,
} //若右孩子不为空,则进入if,依次循环下去,直到while条件不满足
void preordertraver(Bitree p)//非递归先序.栈
{
linkstack *r;
r=(linkstack*)malloc(sizeof(linkstack));
inistack(r);
Bitree t;
t=p;
while(t||!stackempty(r))
{
if(t){push(r,t);t=gettop(r);visit(t);t=t->lchild;}//类似上面,不过在push之后就要输出push的值
else { //但是不能pop出去,如果pop出去了,只能遍历每行最左边的节点
t=pop(r);//找到一个节点,它为空,t等于出栈元素(即t的父节点!)
t=t->rchild;//让t指向它的右孩子,为空时继续进入else,pop栈顶,不为空时进入if,再做刚才的判断
}
}
}
void postordertraver(Bitree p)//后序非递归遍历.栈
{
linkstack *r;
r=(linkstack*)malloc(sizeof(linkstack));
inistack(r);
Bitree t,l;
t=p;l=NULL;
while(t){push(r,t);t=t->lchild;}//最左边节点均入栈!最终push的是二叉树最左边的节点
while(!stackempty(r))
{
t=gettop(r);//获得栈顶节点
if(!t->rchild||l==t->rchild){l=pop(r);visit(l);}//如果t右孩子节点为空或已被访问,则pop掉,l记录位置
else { //l总是所在判断的节点的上一个被删除的节点
t=t->rchild;//t右节点不为空且右节点未被访问,t=rchild;
while(t){push(r,t);t=t->lchild;}//如果更新后的节点不为空,则左孩子while入栈,只到没有左孩子节点
}
}
}