树和二叉树一 数据结构实验.docx
- 文档编号:24896779
- 上传时间:2023-06-02
- 格式:DOCX
- 页数:22
- 大小:70.35KB
树和二叉树一 数据结构实验.docx
《树和二叉树一 数据结构实验.docx》由会员分享,可在线阅读,更多相关《树和二叉树一 数据结构实验.docx(22页珍藏版)》请在冰豆网上搜索。
树和二叉树一数据结构实验
实验报告
May14
2015
姓名:
陈斌学号:
E11314079专业:
13计算机科学与技术
数据结构第三次实验
学号E11314079专业计算机科学与技术姓名陈斌
实验日期2015.05.14教师签字成绩
实验报告
【实验名称】树和二叉树
(一)
【实验目的】
1.掌握二叉树的二叉链表存储表示;
2.掌握二叉树的遍历算法;
3.运用遍历算法求解有关问题。
【实验内容】
1.必做内容
任务1:
以算法6.4创建二叉树的存储结构,树的具体形态自定。
任务2:
对任务1中的二叉树分别实现先序、中序、后序遍历(递归实现)和中序遍历的非递归实现以及层序遍历;
任务3:
统计1中树的结点总数、叶子结点总数以及树的高度;
源代码:
head.h:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//函数结果状态代码
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
//OVERFLOW在math.h中已定义为3
typedefintStatus;
typedefintBoolean;//布尔类型
head2.h:
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
typedefstruct{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
typedefstructQNode
{
QElemTypedata;
structQNode*next;
}QNode,*QueuePtr;
typedefstruct
{
QueuePtrfront,rear;/*队头、队尾指针*/
}LinkQueue;
StatusInitStack(SqStack&S)
{/*构造一个空栈S*/
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
S.base)
exit(OVERFLOW);/*存储分配失败*/
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
returnOK;
}
StatusStackEmpty(SqStack&S)
{/*若栈S为空栈,则返回TRUE,否则返回FALSE*/
if(S.top==S.base)
returnTRUE;
else
returnFALSE;
}
StatusGetTop(SqStack&S,QElemType&e)
{/*若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR*/
if(S.top>S.base)
{
e=*(S.top-1);
returnOK;
}
else
returnERROR;
}
StatusPush(SqStack&S,QElemType&e)
{/*插入元素e为新的栈顶元素*/
if(S.top-S.base>=S.stacksize)/*栈满,追加存储空间*/
{
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.base)
exit(OVERFLOW);/*存储分配失败*/
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
returnOK;
}
StatusPop(SqStack&S,QElemType&e)
{/*若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR*/
if(S.top==S.base)
returnERROR;
e=*--S.top;
returnOK;
}
StatusInitQueue(LinkQueue&Q)
{/*构造一个空队列Q*/
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!
Q.front)
exit(OVERFLOW);
Q.front->next=NULL;
returnOK;
}
StatusQueueEmpty(LinkQueue&Q)
{/*若Q为空队列,则返回TRUE,否则返回FALSE*/
if(Q.front==Q.rear)
returnTRUE;
else
returnFALSE;
}
StatusEnQueue(LinkQueue&Q,QElemTypee)
{/*插入元素e为Q的新的队尾元素*/
QueuePtrp=(QueuePtr)malloc(sizeof(QNode));
if(!
p)/*存储分配失败*/
exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
returnOK;
}
StatusDeQueue(LinkQueue&Q,QElemType&e)
{/*若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR*/
QueuePtrp;
if(Q.front==Q.rear)
returnERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
returnOK;
}
main.cpp:
typedefcharTElemType;
#include"head.h"
typedefstructBiTNode{
TElemTypedata;
structBiTNode*lchild,*rchild;
}BiTNode,*BiTree;
typedefBiTreeQElemType;/*设队列元素为二叉树的指针类型*/
typedefBiTreeSElemType;/*设栈元素为二叉树的指针类型*/
#include"head2.h"
StatusInitBiTree(BiTree&T)
{/*操作结果:
构造空二叉树T*/
T=NULL;
returnOK;
}
StatusCreateBiTree(BiTree&T)
{//算法6.4:
按先序次序输入二叉树中结点的值(字符型),构造二叉链表表示的二叉树T。
TElemTypech;
scanf("%c",&ch);
if(ch=='')/*空*/
T=NULL;
else
{
T=(BiTree)malloc(sizeof(BiTNode));
if(!
T)
exit(OVERFLOW);
T->data=ch;/*生成根结点*/
CreateBiTree(T->lchild);/*构造左子树*/
CreateBiTree(T->rchild);/*构造右子树*/
}
returnOK;
}
StatusPreOrderTraverse(BiTreeT,Status(*Visit)(TElemType))
{/*初始条件:
二叉树T存在,Visit是对结点操作的应用函数。
算法6.1*/
/*操作结果:
先序递归遍历T,对每个结点调用函数Visit一次且仅一次*/
if(T)/*T不空*/
{
if(Visit(T->data))/*先访问根结点*/
if(PreOrderTraverse(T->lchild,Visit))/*再先序遍历左子树*/
if(PreOrderTraverse(T->rchild,Visit))/*最后先序遍历右子树*/
returnOK;
returnERROR;
}
else
returnOK;
}
StatusInOrderTraverse(BiTreeT,Status(*Visit)(TElemType))
{/*初始条件:
二叉树T存在,Visit是对结点操作的应用函数*/
/*操作结果:
中序递归遍历T,对每个结点调用函数Visit一次且仅一次*/
if(T)
{
if(InOrderTraverse(T->lchild,Visit))/*先中序遍历左子树*/
if(Visit(T->data))/*再访问根结点*/
if(InOrderTraverse(T->rchild,Visit))/*最后中序遍历右子树*/
returnOK;
returnERROR;
}
else
returnOK;
}
StatusPostOrderTraverse(BiTreeT,Status(*Visit)(TElemType))
{/*初始条件:
二叉树T存在,Visit是对结点操作的应用函数*/
/*操作结果:
后序递归遍历T,对每个结点调用函数Visit一次且仅一次*/
if(T)/*T不空*/
{
if(PostOrderTraverse(T->lchild,Visit))/*先后序遍历左子树*/
if(PostOrderTraverse(T->rchild,Visit))/*再后序遍历右子树*/
if(Visit(T->data))/*最后访问根结点*/
returnOK;
returnERROR;
}
else
returnOK;
}
StatusInOrderTraverse1(BiTreeT,Status(*Visit)(TElemType))
{/*采用二叉链表存储结构,Visit是对数据元素操作的应用函数。
*/
/*中序遍历二叉树T的非递归算法(利用栈),对每个数据元素调用函数Visit*/
SqStackS;
InitStack(S);
while(T||!
StackEmpty(S))
{
if(T)
{/*根指针进栈,遍历左子树*/
Push(S,T);
T=T->lchild;
}
else
{/*根指针退栈,访问根结点,遍历右子树*/
Pop(S,T);
if(!
Visit(T->data))
returnERROR;
T=T->rchild;
}
}
printf("\n");
returnOK;
}
StatusInOrderTraverse2(BiTreeT,Status(*Visit)(TElemType))
{/*采用二叉链表存储结构,Visit是对数据元素操作的应用函数。
算法6.2*/
/*中序遍历二叉树T的非递归算法(利用栈),对每个数据元素调用函数Visit*/
SqStackS;
BiTreep;
InitStack(S);
Push(S,T);/*根指针进栈*/
while(!
StackEmpty(S))
{
while(GetTop(S,p)&&p)
Push(S,p->lchild);/*向左走到尽头*/
Pop(S,p);/*空指针退栈*/
if(!
StackEmpty(S))
{/*访问结点,向右一步*/
Pop(S,p);
if(!
Visit(p->data))
returnERROR;
Push(S,p->rchild);
}
}
printf("\n");
returnOK;
}
voidLevelOrderTraverse(BiTreeT,Status(*Visit)(TElemType))
{/*初始条件:
二叉树T存在,Visit是对结点操作的应用函数*/
/*操作结果:
层序递归遍历T(利用队列),对每个结点调用函数Visit一次且仅一次*/
LinkQueueq;
QElemTypea;
if(T)
{
InitQueue(q);
EnQueue(q,T);
while(!
QueueEmpty(q))
{
DeQueue(q,a);
Visit(a->data);
if(a->lchild!
=NULL)
EnQueue(q,a->lchild);
if(a->rchild!
=NULL)
EnQueue(q,a->rchild);
}
printf("\n");
}
}
StatusvisitT(TElemTypee)
{
printf("%c",e);
returnOK;
}
StatusBiTreeNodeNum(BiTreeT)//结点总个数
{
if(T)
returnBiTreeNodeNum(T->lchild)+BiTreeNodeNum(T->rchild)+1;
else
return0;
}
StatusBiTreeLeafNodeNum(BiTreeT)//叶子结点个数
{
if(T)
{
if(!
T->lchild&&!
T->rchild)
return1;
else
returnBiTreeLeafNodeNum(T->lchild)+BiTreeLeafNodeNum(T->rchild);
}
elsereturn0;
}
StatusBiTreeDepth(BiTreeT)//树的深度
{
if(!
T)
return0;
else
return(BiTreeDepth(T->lchild)>BiTreeDepth(T->rchild)?
BiTreeDepth(T->lchild):
BiTreeDepth(T->rchild))+1;
}
voidmain()
{
BiTreeT;
InitBiTree(T);
cout<<"请先序输入二叉树(如:
ab三个空格表示a为根结点,b为左子树的二叉树):
"< CreateBiTree(T); cout<<"先序遍历序列: "< PreOrderTraverse(T,visitT); cout< cout<<"中序遍历序列: "< InOrderTraverse(T,visitT); cout< cout<<"后序遍历序列: "< PostOrderTraverse(T,visitT); cout< cout<<"中序遍历的非递归实现1(利用栈): "< InOrderTraverse1(T,visitT); cout<<"中序遍历的非递归实现2(利用栈): "< InOrderTraverse2(T,visitT); cout<<"层序遍历(利用队列): "< LevelOrderTraverse(T,visitT); cout<<"树的结点总数为: "< cout<<"树的叶子结点总数为: "< cout<<"树的深度为: "< } 运行结果: 树的形状: 先序输入: ABGCDEHF(“”代表空格) 2.选做内容 任务4: 修改算法6.4(结点及二叉树类型分别用BiThrNode,BiThrTree,创建根结点的语句也要进行修改),然后对所创建的二叉树进行中序线索化; 任务5: 对任务4得到的中序线索化树进行中序遍历。 源代码: head.h: #include #include #include #include #include #include #include #include #include #include //函数结果状态代码 #defineTRUE1 #defineFALSE0 #defineOK1 #defineERROR0 #defineINFEASIBLE-1 //OVERFLOW在math.h中已定义为3 typedefintStatus; typedefintBoolean;//布尔类型 head2.h: typedefcharTElemType; typedefenum{Link,Thread}PointerTag;/*Link(0): 指针,Thread (1): 线索*/ typedefstructBiThrNode { TElemTypedata; structBiThrNode*lchild,*rchild;/*左右孩子指针*/ PointerTagLTag,RTag;/*左右标志*/ }BiThrNode,*BiThrTree; main.cpp: #include"head.h" #include"head2.h" StatusCreateBiThrTree(BiThrTree&T) {/*按先序输入二叉线索树中结点的值,构造二叉线索树T*/ /*空格表示空结点*/ TElemTypeh; scanf("%c",&h); if(h=='') T=NULL; else { T=(BiThrTree)malloc(sizeof(BiThrNode)); if(! T) exit(OVERFLOW); T->data=h;/*生成根结点(先序)*/ CreateBiThrTree(T->lchild);/*递归构造左子树*/ if(T->lchild)/*有左孩子*/ T->LTag=Link; CreateBiThrTree(T->rchild);/*递归构造右子树*/ if(T->rchild)/*有右孩子*/ T->RTag=Link; } returnOK; } BiThrTreepre; voidInThreading(BiThrTreep) {/*中序遍历进行中序线索化。 算法6.7*/ if(p) { InThreading(p->lchild);/*递归左子树线索化*/ if(! p->lchild)/*没有左孩子*/ { p->LTag=Thread;/*前驱线索*/ p->lchild=pre;/*左孩子指针指向前驱*/ } if(! pre->rchild)/*前驱没有右孩子*/ { pre->RTag=Thread;/*后继线索*/ pre->rchild=p;/*前驱右孩子指针指向后继(当前结点p)*/ } pre=p;/*保持pre指向p的前驱*/ InThreading(p->rchild);/*递归右子树线索化*/ } } StatusInOrderThreading(BiThrTree&Thrt,BiThrTreeT) {/*中序遍历二叉树T,并将其中序线索化,Thrt指向头结点。 算法6.6*/ Thrt=(BiThrTree)malloc(sizeof(BiThrNode)); if(! Thrt) exit(OVERFLOW); Thrt->LTag=Link;/*建头结点*/ Thrt->RTag=Thread; Thrt->rchild=Thrt;/*右指针回指*/ if(! T)/*若二叉树空,则左指针回指*/ Thrt->lchild=Thrt; else { Thrt->lchild=T; pre=Thrt; InThreading(T);/*中序遍历进行中序线索化*/ pre->rchild=Thrt; pre->RTag=Thread;/*最后一个结点线索化*/ Thrt->rchild=pre; } returnOK; } StatusInOrderTraverse_Thr(BiThrTreeT,Status(*Visit)(TElemType)) {/*中序遍历二叉线索树T(头结点)的非递归算法。 算法6.5*/ BiThrTreep; p=T->lchild;/*p指向根结点*/ while(p! =T) {/*空树或遍历结束时,p==T*/ while(p->LTag==Link) p=p->lchild; if(! Visit(p->data))/*访问其左子树为空的结点*/ returnERROR; while(p->RTag==Thread&&p->rchild! =T) { p=p->rchild; Visit(p->data);/*访问后继结点*/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 树和二叉树一 数据结构实验 二叉 数据结构 实验