(1)实验目的
通过该实验,使学生理解二叉树的链式存储,掌握二叉树的几种遍历算法,并通过该实验使学生理解递归的含义,掌握C语言编写递归函数的方法和注意事项。
(2)实验内容
实现教材中算法6.4描述的二叉树创建算法,在此基础上实现二叉树的先序、后序递归遍历算法、两种非递归中序遍历、层序遍历、求二叉树的深度。
(3)参考界面
printf("***************************************\n");
printf("********** 1.创建二叉树 *********\n");
printf("********** 2.先序遍历二叉树 *********\n");
printf("********** 3.中序遍历二叉树1 *********\n");
printf("********** 4.中序遍历二叉树2 *********\n");
printf("********** 5.后序遍历二叉树 *********\n");
printf("********** 6.层序遍历二叉树 *********\n");
printf("********** 7.求二叉树深度 *********\n");
printf("********** 8.退出 *********\n");
printf("***************************************\n");
(4)验收/测试用例
l 创建
输入 :ABC$$DE$G$$F$$$ ($表示空格)
该输入对应的树如图所示
l 先序 屏幕输出 A B C D E G F
l 后序 屏幕输出 C G E F D B A
l 中序 屏幕输出 C B E G D F A
(两种中序非递归还需看源代码)
l 层序 屏幕输出 A B C D E F G
l 深度 屏幕显示深度为5
ABC##DE#G##F###
A B C # # D E # G # # F # # #
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define OVERFLOW 2
#define OK 1
#define ERROR 0
typedef struct BiTNode {//定义二叉树
char date;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode,*BiTree;
typedef struct sqnode
{
BiTNode *elem;
struct sqnode *next;
}sqnode;
typedef struct sqstack
{
sqnode *base;
sqnode *top;
}sqstack;
typedef struct QNode {//队列节点结构体
BiTree data;
struct QNode *next;
} QNode,*QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;//队头,队尾指针
}LinkQueue;
void initstack(sqstack *ss);
BiTree push(sqstack *ss,BiTree T);
BiTree pop(sqstack *ss,BiTree T);
char CreateBiTree ( BiTree &T)
{
char ch;
ch=getchar();
if(ch=='#')
{
T=NULL;
}
else
{
if(!(T=(BiTree)malloc(sizeof(BiTree))))
printf("内存分配失败!\n");
T->date=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return OK;
}
void PreOrderTraverse(BiTree T) //先序遍历
{
if(T)
{
printf("%c ",T->date);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
int InOrderTraverse1 ( BiTree T )
{
BiTree p=T;
sqstack *S;
S=(sqstack *)malloc(sizeof(sqstack));
initstack(S);
while (p || S->base!=S->top) {
while (p) {
push(S,p);
p=p->lchild;
}
p=pop(S,p);
printf ("%c ",p->date);
p=p->rchild;
}
}
void InOrderTraverse2 ( BiTree T )//中序遍历二叉树1
{
BiTree p=T;
sqstack *S;
S=(sqstack *)malloc(sizeof(sqstack));
initstack (S);
push (S,p);
while (S->base!=S->top)
{
while( p )
{
push (S,p->lchild);
p=p->lchild;
}
p=pop(S,p);
if (S->base!=S->top)
{
p=pop (S,p);
printf ("%c ",p->date);
push (S,p->rchild);
p=p->rchild;
}
}
}
void PostOrderTraverse(BiTree T) //后序遍历
{
if(T)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c ",T->date);
}
}
void InitQueue(LinkQueue *Q)
{
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));
if((*Q).front)
(*Q).front->next=NULL;
}
int QueueEmpty(LinkQueue Q)
{
if(Q.front==Q.rear) return 0;
return 1;
}
void EnQueue(LinkQueue *Q,BiTree T)
{
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if(p)
p->data=T;
p->next=NULL;
(*Q).rear->next=p;
(*Q).rear=p;
}
void DeQueue(LinkQueue *Q,BiTree *e)
{
QueuePtr p;
if((*Q).front!=(*Q).rear)
{
p=(*Q).front->next;
*e=p->data;
(*Q).front->next=p->next;
if((*Q).rear==p)
(*Q).rear=(*Q).front;
free(p);
}
}
void LeveOrderTraverse(BiTree T){/*层次遍历*/
LinkQueue q;
BiTree p;
InitQueue(&q);/*初始化一个空的队列*/
EnQueue(&q,T);/*入队*/
while(QueueEmpty(q))
{
DeQueue(&q,&p);/*出队*/
printf("%c ",p->date);
if(p->lchild)
EnQueue(&q,p->lchild);
if(p->rchild)
EnQueue(&q,p->rchild);
}
}
int deeptree(BiTree T)//二叉树深度
{
int m=0,n=0,max=0;
if(T!=NULL)
{
n=deeptree(T->lchild);
m=deeptree(T->rchild);
if(m>n)
max=m;
else
max=n;
return max+1;
}
else
return 0;
}
int main()
{
printf("***************************************\n");
printf("********** 1.创建二叉树 *********\n");
printf("********** 2.先序遍历二叉树 *********\n");
printf("********** 3.中序遍历二叉树1 *********\n");
printf("********** 4.中序遍历二叉树2 *********\n");
printf("********** 5.后序遍历二叉树 *********\n");
printf("********** 6.层序遍历二叉树 *********\n");
printf("********** 7.求二叉树深度 *********\n");
printf("********** 8.退出 *********\n");
printf("***************************************\n");
while(true)
{
printf("请输入选择:");
int num1;
scanf("%d",&num1);
if(num1==8) break;
BiTree T;
getchar();
switch(num1)
{
case 1:
printf("请输入一串字符串!完成对二叉树的创建!\n");
CreateBiTree(T);
break;
case 2:
printf("先序遍历:");
PreOrderTraverse(T);
printf("\n");
break;
case 3:
printf("中序遍历1:");
InOrderTraverse1 (T);
printf("\n");
break;
case 4:
printf("中序遍历2:");
InOrderTraverse2 (T);
printf("\n");
break;
case 5:
printf("后序遍历:");
PostOrderTraverse(T);
printf("\n");
break;
case 6:
printf ("层次遍历:");
LeveOrderTraverse(T);
printf("\n");
break;
case 7:
printf ("树的深度为:");
printf ("%d\n",deeptree(T));
break;
}
}
return 0;
}
void initstack(sqstack *ss)
{
ss->base=(sqnode *)malloc(sizeof(sqnode));
ss->top=ss->base;
}
BiTree push(sqstack *ss,BiTree T)
{
sqnode *sn=(sqnode *)malloc(sizeof(sqnode));
sn->next=NULL;
if(!sn)
{
printf("内存申请失败!\n");
return 0;
}
sn->elem=T;
sn->next=ss->top;
ss->top=sn;
return T;
}
BiTree pop(sqstack *ss,BiTree T)
{
if(ss->top==ss->base)
{
printf("栈为空\n");
return 0;
}
sqnode *S=ss->top->next;
T=ss->top->elem;
free(ss->top);
ss->top =S;
return T;
}