树和二叉树一 数据结构实验.docx

上传人:b****4 文档编号:24896779 上传时间:2023-06-02 格式:DOCX 页数:22 大小:70.35KB
下载 相关 举报
树和二叉树一 数据结构实验.docx_第1页
第1页 / 共22页
树和二叉树一 数据结构实验.docx_第2页
第2页 / 共22页
树和二叉树一 数据结构实验.docx_第3页
第3页 / 共22页
树和二叉树一 数据结构实验.docx_第4页
第4页 / 共22页
树和二叉树一 数据结构实验.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

树和二叉树一 数据结构实验.docx

《树和二叉树一 数据结构实验.docx》由会员分享,可在线阅读,更多相关《树和二叉树一 数据结构实验.docx(22页珍藏版)》请在冰豆网上搜索。

树和二叉树一 数据结构实验.docx

树和二叉树一数据结构实验

实验报告

May14

2015

姓名:

陈斌学号:

E11314079专业:

13计算机科学与技术

数据结构第三次实验

学号E11314079专业计算机科学与技术姓名陈斌

实验日期2015.05.14教师签字成绩

实验报告

【实验名称】树和二叉树

(一)

【实验目的】

1.掌握二叉树的二叉链表存储表示;

2.掌握二叉树的遍历算法;

3.运用遍历算法求解有关问题。

【实验内容】

1.必做内容

任务1:

以算法6.4创建二叉树的存储结构,树的具体形态自定。

任务2:

对任务1中的二叉树分别实现先序、中序、后序遍历(递归实现)和中序遍历的非递归实现以及层序遍历;

任务3:

统计1中树的结点总数、叶子结点总数以及树的高度;

源代码:

head.h:

#include

#include

#include//malloc()

#include//INT,MAX

#include//EOF,NULL

#include//atoi()

#include//eof()

#include//floor(),ceil(),abs()

#include//exit()

#include//cout,cin

//函数结果状态代码

#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//malloc()

#include//INT,MAX

#include//EOF,NULL

#include//atoi()

#include//eof()

#include//floor(),ceil(),abs()

#include//exit()

#include//cout,cin

//函数结果状态代码

#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);/*访问后继结点*/

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1