本期的内容是“二叉树的前序、中序、后序遍历”
理论就不多嗦了,测试用的树是:
图片来源:王道考研数据结构PPT,侵权请联系删除
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
/*链式存储二叉树的先序、中序、后序、层序遍历*/
typedef struct BiTNode{
char data;
struct BiTNode* lchild;
struct BiTNode* rchild;
}BiTNode,*BiTree;
void visit(BiTNode *t){
printf("%c",t->data);
}
//这里编写一个链式队列,提供给层序遍历使用
typedef struct LNode{
BiTNode data;
struct LNode *next;
}LNode;
typedef struct{
LNode *front,*rear;//队列头指针尾指针
}LinkQueue;
void InitQueue(LinkQueue *Q)
{
Q->front=Q->rear=(LNode*)malloc(sizeof(LNode));//初始状态队列的头节点和尾结点都指向头节点
Q->front->next=NULL;
}
bool IsEmpty(LinkQueue Q)//判断队列是否为空
{
if(Q.front==Q.rear)
return true;
else
return false;
}
void Enqueue(LinkQueue *Q,BiTNode N)//入队操作
{
//给队列创建一个新的结点,存储要入队的数据
LNode *s=(LNode*)malloc(sizeof(LNode));
s->data=N;
s->next=NULL;
//将这个结点接入队列中
Q->rear->next=s;//将这个结点放到队尾指针之后
Q->rear=s;//队尾指针指向新元素
}
bool Dequeue(LinkQueue *Q, BiTNode *T)//出队操作
{
if(IsEmpty(*Q))
return true;
LNode *p;
p=Q->front->next;
(*T)=p->data;//用T返回我们要删除的结点,便于后续访问这个结点的值
Q->front->next=p->next;
if(Q->rear==p)//这个情况是队列中只有一个元素,要把头指针和尾指针都指向头节点(不存数据)
{
Q->rear=Q->front;
}
free(p);
return false;
}
//正片开始
//二叉树的先序遍历
void PreOrder(BiTree T)
{
if(T!=NULL)//如果不是空树就进行遍历
{
visit(T);//访问根节点
PreOrder(T->lchild);//以先序遍历的方式递归遍历左子树
PreOrder(T->rchild);//以先序遍历的方式递归遍历右子树
}
}
//二叉树的中序遍历
void InOrder(BiTree T){
if(T!=NULL)
{
InOrder(T->lchild);//先用中序的方式访问左子树
visit(T);//在访问本结点
InOrder(T->rchild);//在用中序的方式访问右子树
}
}
//二叉树后序遍历
void PostOrder(BiTree T){
if(T!=NULL){
PostOrder(T->lchild);//先以后序的方式遍历左子树
PostOrder(T->rchild);//在以后序的方式遍历右子树
visit(T);//最后访问根节点
}
}
/* 二叉树层序遍历
1.初始化一个辅助队列
2.根节点入队
3.若队列非空,则头节点出队,并将改头节点的左右子节点插入队尾
4.重复步骤3直到队列为空
*/
void LevelOrder(BiTree T)
{
LinkQueue Q;
BiTNode n;//我们目前访问到的结点,也就是出队结点
InitQueue(&Q);
Enqueue(&Q,*T);
while(!IsEmpty(Q))
{
Dequeue(&Q,&n);
visit(&n);
if(n.lchild!=NULL)
Enqueue(&Q , *(n.lchild));
if(n.rchild!=NULL)
Enqueue(&Q, *(n.rchild));
}
}
void test01()
{
BiTree A;//创建一棵用于测试的树
A=(BiTNode*)malloc(sizeof(BiTNode));//给头节点分配空间
A->data='A';
//创建几个节点,准备形成一棵树
BiTNode *B;
B=(BiTNode*)malloc(sizeof(BiTNode));
B->data='B';
BiTNode *C;
C=(BiTNode*)malloc(sizeof(BiTNode));
C->data='C';
BiTNode *D;
D=(BiTNode*)malloc(sizeof(BiTNode));
D->data='D';
BiTNode *E;
E=(BiTNode*)malloc(sizeof(BiTNode));
E->data='E';
BiTNode *F;
F=(BiTNode*)malloc(sizeof(BiTNode));
F->data='F';
BiTNode *G;
G=(BiTNode*)malloc(sizeof(BiTNode));
G->data='G';
//把这些结点连成二叉树
A->lchild=B;
A->rchild=C;
B->lchild=D;
B->rchild=E;
C->lchild=F;
C->rchild=NULL;
D->lchild=NULL;
D->rchild=G;
E->lchild=NULL;
E->rchild=NULL;
F->lchild=NULL;
F->rchild=NULL;
G->lchild=NULL;
G->rchild=NULL;
PreOrder(A);
printf("\n\n");
InOrder(A);
printf("\n\n");
PostOrder(A);
printf("\n\n");
LevelOrder(A);
}
int main()
{
test01();
return 0;
}