数据结构树的实现实验报告.docx
- 文档编号:26731753
- 上传时间:2023-06-22
- 格式:DOCX
- 页数:43
- 大小:293.18KB
数据结构树的实现实验报告.docx
《数据结构树的实现实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构树的实现实验报告.docx(43页珍藏版)》请在冰豆网上搜索。
数据结构树的实现实验报告
数据结构设计性实验报告
课程名称_________
题目名称
学生学院
专业班级
学号
学生姓名
指导教师
2010年7月6日
抽象数据类型:
树的实现
一.需求分析
树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用,直观来看,树是以分支关系定义的内部结构。
树的结构在客观世界广泛存在,如人类社会的族谱和各种社会组织机构都可以用树来形象表示。
树在计算机领域中也得广泛应用,如在编译程序中,可用树来表示源程序的语法结构,又如在数据库系统中,树形结构也是信息的重要组织形式之一。
二.实验目的
对某个具体的抽象数据类型,运用课程所学的知识和方法,设计合理的数据结构,并在此基础上实现该抽象数据类型的全部基本操作。
通过本设计性实验,检验所学知识和能力,发现学习中存在的问题。
进而达到熟练地运用本课程中的基础知识及技术的目的。
三.实验环境
1、硬件:
PC机
2、软件:
MicrosoftVisualC++6.0
四.设计说明
本程序采用树的二叉链表(孩子指针-兄弟指针-双亲指针)存储表示,以下是树的结构定义和基本操作:
ADTTree{
数据对象D:
D是具有相同特性的数据元素的集合。
数据关系R:
若D为空集,则称为空树;
若D仅含有一个数据元素,则R为空集,否则R={H},H是如下二元关系:
(1)在D中存在唯一的称为根的数据元素root,它在关系H下无前驱;
(2)若D-{root}≠NULL,则存在D-{root}的一个划分D1,D2,D3,…,Dm(m>0),对于任意j≠k(1≤j,k≤m)有Dj∩Dk=NULL,且对任意的i(1≤i≤m),唯一存在数据元素xi∈Di有
(3)对应于D-{root}的划分,H-{
基本操作P:
InitTree(&T);
操作结果:
构造空树T。
DestroyTree(&T);
初始条件:
树T存在。
操作结果:
销毁树T。
CreateTree(&T,definition);
初始条件:
definition给出树T的定义。
操作结果:
按definition构造树T。
ClearTree(&T);
初始条件:
树T存在。
操作结果:
将树T清为空树。
TreeEmpty(T);
初始条件:
树T存在。
操作结果:
若T为空树,则返回TRUE,否则返回FALSE。
TreeDepth(T);
初始条件:
树T存在。
操作结果:
返回T的深度。
Root(T);
初始条件:
树T存在。
操作结果:
返回T的根。
Value(T,cur_e);
初始条件:
树T存在,cur_e是T中某个结点。
操作结果:
返回cur_e的值。
Assign(T,cur_e,value);
初始条件:
树T存在,cur_e是T中某个结点。
操作结果:
结点cur_e赋值为value。
Parent(T,cur_e);
初始条件:
树T存在,cur_e是T中某个结点。
操作结果:
若cur_e是T的非根结点,则返回它的双亲,否则函数值为“空”。
LeftChild(T,cur_e);
初始条件:
树T存在,cur_e是T中某个结点。
操作结果:
若cur_e是T的非叶子结点,则返回它的最左孩子,否则返回“空”。
RightSibling(T,cur_e);
初始条件:
树T存在,cur_e是T中某个结点。
操作结果:
若cur_e有右兄弟,则返回它的右兄弟,否则返回“空”。
InsertChild(&T,&p,I,c);
初始条件:
树T存在,p指向T中某个结点,1≤i≤p指结点的度+1,非空树c与T不相交。
操作结果:
插入c为T中p指结点的第i棵子树。
DeleteChild(&T,&p,i);
初始条件:
树T存在,p指向T中某个结点,1≤i≤p指结点的度。
操作结果:
删除T中p所指结点的第i棵子树。
TraverseTree(T,visit());
初始条件:
树T存在,visit是对结点操作的应用函数。
操作结果:
按某种次序对T的每个结点调用函数visit()一次且至多一次。
一旦visit()失败,则操作失败。
CSTreeSearch(CSTreeT,TElemTypecur_e);
初始条件:
树T存在,cur_e可能是树T中某一个结点的值。
操作结果:
在树T中查找值为cur_e的结点,找到返回指向这个结点的指针,否则返回空指针。
这个函数的作用是为了几个基本操作而服务的。
voidLevelOrderTraverseTree(CSTreeT,void(*visit)(TElemType));
初始条件:
树T存在,visit是对结点操作的应用函数。
操作结果:
按层次次序对T的每一个结点调用函数visit()一次且至多一次。
voidPreOrderTraverseTree(CSTreeT,void(*visit)(TElemType));
初始条件:
树T存在,visit是对结点操作的应用函数。
操作函数:
按先序次序(先根遍历)对T的每一个结点调用函数visit()一次且至多一次。
函数的功能实现是递归实现的。
voidPostOrderTraverseTree(CSTreeT,void(*visit)(TElemType));
初始条件:
树T存在,visit是对结点操作的应用函数。
操作结果:
按后根遍历对T的每一个结点调用函数visit()一次且至多一次。
函数的功能实现是递归实现的。
voidvisit_print(CSTreep);
初始条件:
树T存在,visit_print是对结点操作的应用函数。
操作函数:
对T的每一个结点调用函数visit_print()一次且至多一次。
与visit函数不一样的是,visit函数只是输出一个结点的值,而visit_print还输出其结点,第一个孩子,其右兄弟和双亲的值
voidPrint(CSTreeT,void(*visit)(CSTree));
附加函数:
用于显示树的所有内容。
初始条件:
树T存在;
操作结果:
将树T的所有结点显示出来。
}ADTTree
五.
数据处理
树型数据存储样本:
转化后树的二叉链表存储:
以下为数据样本测试:
●操作:
判断树书否为空?
结果:
不为空
●返回树T的深度?
结果:
4
●返回树T的根结点?
结果:
A
●返回树F结点的值?
结果:
F
●将树根节点重新赋值为W?
结果:
A<—>W
●求出结点A的双亲?
结果:
W
●求出结点A的第一个孩子结点?
结果:
D
●求出G的第一个兄弟结点?
结果:
H
●
插入子树C至A中第2科子树?
结果:
●删除树结点为R的第三颗子树?
结果:
●多种遍历方式遍历树
前序遍历树:
W-A-D-X-Y-Z-E-B
层次序遍历树:
W-A-B-D-X-E-Y-Z
后序遍历树:
D-Y-Z-X-E-A-B-W
以下为运行EXE程序测试过程:
选择1:
选择14:
选择15:
选择16:
选择4:
选择5:
选择6:
选择7:
选择8:
选择9:
选择10:
选择11:
选择12:
选择13:
选择14:
选择15:
选择16:
选择2:
六.程序清单解读
/**************************抽象数据类型树-源码*********************************/
#include
#include
usingnamespacestd;
constintTRUE=1;
constintFALSE=0;
constintOK=1;
constintERROR=0;
constintOVERFLOW=1;
constintMAX=30;
constcharNIL='';
/*****************树的二叉链表孩子-兄弟-双亲存储表示***************************/
typedefstructCSnode
{
chardata;
CSnode*firstchild,*nextsibling,*parent;
/*最左孩子指针、下一个兄弟指针、双亲指针*/
}CSNode,*CSTree;
/********************树的辅助队列结构定义和操作******************************/
typedefstructQNode
{
CSTreedata;
QNode*next;
}QNode,*QueuePtr;/*队列的单链式存储结构*/
typedefstructLinkQueue
{
QueuePtrfront,rear;/*队头、队尾指针*/
}LinkQueue;
/*******************************队列定义**************************************/
/*构造一个空队列*/
intInitQueue(LinkQueue&Q)
{
if(!
(Q.front=Q.rear=newQNode))
exit(OVERFLOW);
Q.front->next=NULL;
returnOK;
}
/*销毁队列Q*/
intDestroyQueue(LinkQueue&Q)
{
while(Q.front){
Q.rear=Q.front->next;
deleteQ.front;
Q.front=Q.rear;
}
returnOK;
}
/*将Q清为空队列*/
intClearQueue(LinkQueue&Q)
{
QueuePtrp,q;
Q.rear=Q.front;
p=Q.front->next;
Q.front->next=NULL;
while(p){
q=p;
p=p->next;
deleteq;
}
returnOK;
}
/*若队列Q为空队列则返回TRUE,否则返回FALSE*/
intQueueEmpty(LinkQueueQ)
{
if(Q.front==Q.rear)returnTRUE;
elsereturnFALSE;
}
/*插入元素e为Q的新的队尾元素*/
intEnQueue(LinkQueue&Q,CSTreee)
{
QueuePtrp;
if(!
(p=newQNode))exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
returnOK;
}
/*若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR*/
intDeQueue(LinkQueue&Q,CSTree&e)
{
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;
deletep;
returnOK;
}
/*****************************************************************************/
/***********************树的二叉链表孩子-兄弟-双亲存储定义*********************/
/*操作结果:
构造空树T*/
intInitTree(CSTree&T)
{
T=NULL;
returnOK;
}
/*初始条件:
树T存在*/
/*操作结果:
销毁树T*/
voidDestroyTree(CSTree&T)
{
if(T)
{
if(T->firstchild)DestroyTree(T->firstchild);
if(T->nextsibling)DestroyTree(T->nextsibling);
deleteT;
}
}
/*初始条件:
树T存在*/
/*操作结果:
按层次次序创建树T*/
intCreateTree(CSTree&T)
{
charc[MAX];
CSTreep,p1,temp;
LinkQueueq;
InitQueue(q);
cout<<"请输入根节点,空格代表跟为空:
";
fflush(stdin);
c[0]=getche();
if(c[0]!
=NIL)/*非空树*/
{
T=newCSNode;
T->data=c[0];
T->nextsibling=NULL;
T->parent=NULL;
EnQueue(q,T);
while(!
QueueEmpty(q))
{
DeQueue(q,p);
cout<<"\n请输入"<
";
gets(c);
if(strlen(c))/*树有孩子*/
{
p1=p->firstchild=newCSNode;/*建立长子节点*/
temp=p;/*保存该根节点*/
p1->parent=temp;/*建立双亲域*/
p1->data=c[0];
EnQueue(q,p1);/*第一个孩子节点入队列*/
for(inti=1;i { p1->nextsibling=newCSNode;/*建立下一个兄弟节点*/ p1->nextsibling->data=c[i];/*下一个兄弟节点赋值*/ p1->nextsibling->parent=temp;/*建立下一个兄弟节点双亲域*/ EnQueue(q,p1->nextsibling);/*各兄弟入队*/ p1=p1->nextsibling; } p1->nextsibling=NULL;/*最后的兄弟结点的nextsibling指针置为空*/ } else/*树无孩子只有根节点*/ { p->firstchild=NULL; } } } elseT=NULL;/*空树*/ returnOK; } /*初始条件: 树T存在*/ /*操作结果: 将树T清为空树*/ voidClearTree(CSTree&T) { if(T) { if(T->firstchild)DestroyTree(T->firstchild); if(T->nextsibling)DestroyTree(T->nextsibling); deleteT; T=NULL; } } /*初始条件: 树T存在*/ /*操作结果: 若T为空树,则返回TRUE,否则返回FALSE*/ intTreeEmpty(CSTreeT) { if(T==NULL)returnTRUE; elsereturnFALSE; } /*初始条件: 树T存在*/ /*操作条件: 返回T的深度*/ intTreeDepth(CSTreeT) { CSTreep; intdepth,max=0; if(! T)return0; if(! T->firstchild)return1; for(p=T->firstchild;p;p=p->nextsibling) { depth=TreeDepth(p);/*递归求深度*/ if(depth>max)max=depth; } returnmax+1;/*返回深度要加上根节点*/ } /*初始条件: 树T存在*/ /*操作结果: 返回T的根*/ charRoot(CSTreeT) { if(T)returnT->data; else { cout<<"\n树空,无根节点! "; returnNIL; } } /*初始条件: 树T存在,cur_e可能是树T中某一个结点的值。 */ /*操作结果: 在树T中查找值为cur_e的结点,找到返回指向这个结点的指针,否则返回空指针。 */ CSTreeSearch(CSTreeT,charcur_e) { LinkQueueq; CSTreea; if(T) { InitQueue(q);/*队列初始化*/ EnQueue(q,T); while(! QueueEmpty(q)){ DeQueue(q,a); if(a->data==cur_e)returna; if(a->firstchild)EnQueue(q,a->firstchild); if(a->nextsibling)EnQueue(q,a->nextsibling); } } returnNULL; } /*初始条件: 树T存在,cur_e可能是树T中某个结点*/ /*操作结果: 返回cur_e的值*/ charValue(CSTreeT,charcur_e) { CSTreep; if(T) { p=Search(T,cur_e); if(p)returnp->data; else { cout<<"\n在树中找不到值为"< returnNIL; } } else { cout<<"\n树空,无值为"< returnNIL; } } /*初始条件: 树T存在,cur_e可能是T中的某个结点*/ /*操作结果: 若cur_e是T的非根结点,则返回它的双亲,否则函数值为空*/ charParent(CSTreeT,charcur_e) { CSTreep; if(T) { p=Search(T,cur_e); if(! p) { cout<<"\n在树中找不到值为"< returnNIL; } elseif(! p->parent) { cout<<"\n值为"< returnNIL; } elsereturnp->parent->data; } else { cout<<"\n树空,无节点"; returnNIL; } } /*初始条件: 树T存在,cur_e是树T中结点的值*/ /*操作结果: 改cur_e为value*/ intAssign(CSTree&T,charcur_e,charvalue) { CSTreep; if(T) { p=Search(T,cur_e); if(p) { cout<<"\n找到节点"< p->data=value; returnOK; } else { cout<<"\n找不到节点"< returnERROR; } } else { cout<<"\n树为空,操作无法完成"; returnERROR; } } /*初始条件: 树T存在,cur_e可能是T中某个结点*/ /*操作结果: 若cur_e是T的非叶子结点,则返回它的最左孩子,否则返回函数值为空。 */ charLeftChild(CSTreeT,charcur_e) { CSTreep; if(T) { p=Search(T,cur_e); if(! p) { cout<<"\n找不到值为"< returnNIL; } else { if(! p->firstchild) { cout<<"\n无左孩子"; returnNIL; } else { returnp->firstchild->data; } } } else { cout<<"\n树空,不存在值为"< returnNIL; } } /*初始条件: 树T存在,cur_e可能是T中的某个结点*/ /*操作结果: 若cur_e有右兄弟,则返回它的右兄弟,否则返回函数值为空*/ charRightSibling(CSTreeT,charcur_e) { CSTreep; if(T) { p=Search(T,cur_e); if(! p) { cout<<"\n找不到值为"< returnNIL; } else { if(! p->nextsibling) { cout<<"\n无兄弟"; returnNIL; } else { returnp->nextsibling->data; } } } else { cout<<"\n树空,不存在值为"< returnNIL; } } /*初始条件: 树T存在,p指向T中某个结点,1<=i<=p所指结点的度+1,非空树c与T不相交*/ /*操作结果: 插入c为T中p指结点的第i棵子树*/ intInsertChild(CSTree&T,CSTreep,inti,CSTreec) { CSTreetemp=p;/*保存根节点*/ in
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实现 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)