广东工业大学数据结构二叉树课程设计.doc
《广东工业大学数据结构二叉树课程设计.doc》由会员分享,可在线阅读,更多相关《广东工业大学数据结构二叉树课程设计.doc(21页珍藏版)》请在咨信网上搜索。
数据结构实验报告 题目:二叉树抽象数据类型 学 院 计算机学院 专 业 计算机科学与技术 年级班别 学 号 学生姓名 指导教师 成 绩 ____________________ 2013年6月 一.实验概要 实验项目名称: 二叉树抽象数据类型的实现 实验项目性质: 设计性实验 所属课程名称: 数据结构 实验计划学时: 6 二.实验目的 1. 了解二叉树的定义以及各项基本操作。 2. 实现二叉树存储、遍历及其他基本功能 三. 实验仪器设备和材料 硬件:PC机 软件:Visual C++ 6.0 四.实验的内容 1.二叉树类型定义以及各基本操作的简要描述; ADT BinaryTree { 数据对象D:D是具有相同特性的数据元素的集合. 数据关系R: 若D=∅,则R=,称BinaryTree为空二叉树; 若D≠,则R={H},H是如下二元关系: (1) 在D中存在惟一的称为根的数据元素root,它在关系H下无前驱; (2) 若D-{root}≠∅,则存在D-{root}={D1,Dr},且D1∩Dr=∅; (3) 若D1≠∅,则D1中存在惟一的元素x1,<root,x1>∈H,且存在Dr上的关系Hr∈H;H={<root,x1>,<root,xr>,H1,Hr}; (4) (D1,{H1})是一棵符合本定义的二叉树,称为根的左子树,是一棵符合本定义的二叉树,称为根的右子树。 基本操作P: InitBiTree(&T); 操作结果:构造空二叉树T。 DestroyBiTree(&T); 初始条件:二叉树T存在。 操作结果:销毁二叉树T。 CreateBiTree(&T,definition); 初始条件:definition给出二叉树T的定义。 操作结果:按definition构造二叉树T。 ClearBiTree(&T); 初始条件:二叉树T存在。 操作结果:将二叉树T清为空树。 BiTreeEmpty(T); 初始条件:二叉树T存在。 操作结果:若T为空二叉树,则返回TURE,否则FALSE。 BiTreeDepth(T); 初始条件:二叉树T存在。 操作结果:返回T的深度。 Root(T); 初始条件:二叉树T存在。 操作结果:返回T的根。 Value(T,e); 初始条件:二叉树T存在,e是T中的某个结点。 操作结果:返回e的值。 Assign(T,&e,value); 初始条件:二叉树T存在,e是T中的某个结点。 操作结果:结点e赋值为value。 Parent(T,e); 初始条件:二叉树T存在,e是T中的某个结点。 操作结果:若e是T的非跟结点,则返回它的双亲,否则返回“空”。 LeftChild(T,e); 初始条件:二叉树T存在,e是T中的某个结点。 操作结果:返回e的左孩子。若e无左孩子,则返回“空”。 RightChild(T,e); 初始条件:二叉树T存在,e是T中的某个结点。 操作结果:返回e的右孩子。若e无右孩子,则返回“空”。 LeftSibling(T,e); 初始条件:二叉树T存在,e是T中的某个结点。 操作结果:返回e的左兄弟。若e无左孩子或无左兄弟,则返回“空”。 RightSibling(T,e); 初始条件:二叉树T存在,e是T中的某个结点。 操作结果:返回e的右兄弟。若e无右孩子或无右兄弟,则返回“空”。 }ADT BinaryTree 2.存储结构:采用无头结点的链式存储结构实现 3.源代码: 头文件及存储结构: #include<stdio.h> #include<stdlib.h> #define TURE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVERFLOW 0 #define MAXQSIZE 100 //最大队列长度 typedef char TElemType; typedef struct BiTNode //二叉树结构体 { TElemType data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; typedef BiTree QElemType; typedef struct QNode { QElemType data; struct QNode *next; }QNode, *QueuePtr; //结点结构体 typedef struct { QueuePtr front; QueuePtr rear; }LinkQueue; //链队列结构体 算法设计: int InitQueue(LinkQueue &Q) //构造空队列 { Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode)); if(!Q.front) //存储分配失败 exit(OVERFLOW); Q.front->next = NULL; return OK; } int EnQueue(LinkQueue &Q, QElemType e) //新元素入队尾 { QueuePtr p; p = (QueuePtr)malloc(sizeof(QNode)); if(!p) //存储分配失败 exit (OVERFLOW); p->data = e; p->next = NULL; Q.rear->next = p; Q.rear = p; return OK; } int DeQueue(LinkQueue &Q, QElemType &e) //删除队头元素 { QueuePtr p; if(Q.front == Q.rear) //队列为空队 return ERROR; p = Q.front->next; e = p->data; Q.front->next = p->next; if(Q.rear == p) //判断删除队头元素后,队列是否为空队 Q.rear = Q.front; free(p); return OK; } int QueueEmpty(LinkQueue Q) //判断队列是否为空队 { if (Q.front == Q.rear) return TURE; else return FALSE; } int InitBiTree(BiTree &T) // 构造空二叉树 { T = NULL; return OK; } int DestroyTree(BiTree &T) //销毁二叉树 { if(!T) return ERROR; else DestroyTree(T->lchild); DestroyTree(T->rchild); free(T); T=NULL; return OK; } void CreateBiTree(BiTree &T) //用先序遍历的方式构建二叉树,以‘@’表示空结点。 { TElemType ch; scanf("%c",&ch); if(ch=='@') T=NULL; else { if(!(T=(BiTree)malloc(sizeof(BiTNode)))) exit(OVERFLOW); //分配存储空间失败 T->data=ch; CreateBiTree(T->lchild); //构造左子树 CreateBiTree(T->rchild); //构造右子树 } } int ClearBiTree(BiTree &T) //清空二叉树函数 { if(!T) return ERROR; else { ClearBiTree(T->lchild); ClearBiTree(T->rchild); free(T); T=NULL; return OK; } } int BiTreeEmpty(BiTree T) //判断二叉树是否为空 { if(!T) return TURE; else return FALSE; } int BiTreeDepth(BiTree T) //计算二叉树深度 { int lcd,rcd; if(!T) return 0; lcd=BiTreeDepth(T->lchild); rcd=BiTreeDepth(T->rchild); return ((lcd>rcd?lcd:rcd)+1); } TElemType Root(BiTree T) //判断二叉树是否空,若非空返回其根 { if(BiTreeEmpty(T)) return NULL; else return (T->data); } TElemType Value(BiTree T,BiTree e) //返回e结点的值 { return e->data; } int Assign(BiTree T,BiTree &e,TElemType value) // 将value的值给结点e { e->data=value; return OK; } TElemType Parent(BiTree T,TElemType e) {//返回双亲 LinkQueue q; QElemType a; if(T) { InitQueue(q); EnQueue(q,T);//树根入队列 while(!QueueEmpty(q))//队不空 { DeQueue (q, a);//出队,队列元素赋给a if(a->lchild&&a->lchild->data==e||a->rchild&&a->rchild->data==e) //找到e return a->data; //返回双亲的值 else { if(a->lchild) EnQueue(q,a->lchild);//入队列左孩子 if(a->rchild) EnQueue(q,a->rchild);//入队列右孩子 } } } return NULL; } BiTree Point(BiTree T,TElemType s)//返回二叉树T中指向元素值为S的结点指针 { LinkQueue q; QElemType a; if(T) { InitQueue(q); EnQueue(q,T); while(!QueueEmpty(q)) { DeQueue(q,a); if(a->data==s) { return a; } if(a->lchild) { EnQueue(q,a->lchild); } if(a->rchild) { EnQueue(q,a->rchild); } } } return NULL; } TElemType LeftChild(BiTree T,TElemType e) {//返回e的左孩子 BiTree a; if(T) { a=Point(T,e);//a是指向结点e的指针 if(a&&a->lchild) return a->lchild->data; } return NULL; } TElemType RightChild(BiTree T,TElemType e) //返回e的右孩子 { BiTree a; if(T) { if((a=Point(T,e))&&a->rchild) return a->rchild->data; } return NULL; } TElemType LeftSibling(BiTree T,TElemType e) { //返回左兄弟 TElemType a; BiTree p; if(T) { a=Parent(T,e);//a为e的双亲 if(a!=NULL) { p=Point(T,a);//p指向结点a的指针 if(p->lchild&&p->rchild&&p->rchild->data==e)//p存在左右孩子而且右孩子是e return p->lchild->data; } } return NULL; } TElemType RightSibling(BiTree T,TElemType e) { //返回右兄弟 TElemType a; BiTree p; if(T) { a=Parent(T,e);//a为e的双亲 if(a!=NULL) { p=Point(T,a);//p指向结点a的指针 if(p->lchild&&p->rchild&&p->lchild->data==e)//p存在左右孩子而且左孩子是e return p->rchild->data; } } return NULL; } int InsertChild(BiTree T,BiTree p,int LR,BiTree c) //根据LR为0或者1,插入C为T中P所指结点的左或者右子树, //P所指的结点原有左或右子树则成为C的右子树 { if(p) { if(LR==0) //把二叉树C插入p所指结点的左子树 { c->rchild=p->lchild; p->lchild=c; } else { c->rchild=p->rchild; p->rchild=c; } return OK; } return ERROR; } int DeleteChild(BiTree T,BiTree p,int LR) { if(p) { if(LR==0) { ClearBiTree(p->lchild); } else { ClearBiTree(p->rchild); } return OK; } return ERROR; } void visit(TElemType e) //二叉树结点访问函数 { printf("%c",e); } int PreOrderTraverse(BiTree T,void(*visit)(TElemType)) //先序遍历二叉树 { if(T) { visit(T->data); PreOrderTraverse(T->lchild,visit); PreOrderTraverse(T->rchild,visit); return OK; } return ERROR; } int InOrderTraverse(BiTree T,void(*visit)(TElemType)) { //中序遍历二叉树 if(T) { InOrderTraverse(T->lchild,visit); visit(T->data); InOrderTraverse(T->rchild,visit); return OK; } return ERROR; } int PostOrderTraverse(BiTree T,void(*visit)(TElemType)) { //后序遍历二叉树 if(T) { PostOrderTraverse(T->lchild,visit); PostOrderTraverse(T->rchild,visit); visit(T->data); return OK; } return ERROR; } int LevelOrderTraverse(BiTree T,void(*visit)(TElemType)) {//层序遍历二叉树 LinkQueue q; QElemType a; if(T) { InitQueue(q);//初始化队列 EnQueue(q,T);//根指针入队 while(!QueueEmpty(q)) { DeQueue(q,a);//出队元素,赋给a visit(a->data);//访问a所指结点 if(a->lchild!=NULL) EnQueue(q,a->lchild); if(a->rchild!=NULL) EnQueue(q,a->rchild); } return OK; } return ERROR; } 主函数: int main() { int i,j,LR; TElemType value,a,temp; BiTree p,C; printf("欢迎使用本二叉树程序,请按回车键继续...\n"); getchar(); printf("正在构造空二叉树,请稍候..."); printf("\n"); BiTree T; InitBiTree(T); if(BiTreeEmpty(T)) printf("构造空二叉树成功!\n"); else printf("构造空二叉树失败!\n"); printf("请按先序遍历顺序输入二叉树各结点的值!空结点用@表示!\n"); CreateBiTree(T); printf("\n"); getchar(); printf("请选择接下来的操作:输入“1”为查看二叉树深度,输入“2”为查看二叉树根节点...\n"); scanf("%d",&i); if(i==1) printf("此二叉树的深度为:%d\n\n",BiTreeDepth(T)); if(i==2) printf("此二叉树的根节点为:%c\n\n",Root(T)); printf("请选择遍历该二叉树的顺序:输入“1”为先序遍历,输入“2”为中序遍历,输入“3”为后序遍历,输入“4”为层序遍历...\n"); scanf("%d",&i); getchar(); printf("\n"); if(i==1) { j=PreOrderTraverse(T,visit); printf("\n"); if(j==0) printf("该二叉树为空树,请重新运行程序!\n"); } if(i==2) { j=InOrderTraverse(T,visit); printf("\n"); if(j==0) printf("该二叉树为空树,请重新运行程序!\n"); } if(i==3) { j=PostOrderTraverse(T,visit); printf("\n"); if(j==0) printf("该二叉树为空树,请重新运行程序!\n"); } if(i==4) { j=LevelOrderTraverse(T,visit); printf("\n"); if(j==0) printf("该二叉树为空树,请重新运行程序!\n"); } printf("\n请输入需要替换的结点:\n"); scanf("%c",&a); getchar(); p=Point(T,a); printf("请输入需要代入的结点值:\n"); scanf("%c",&value); getchar(); Assign(T,p,value); printf("赋值之后该结点的值为:%c\n\n",p->data); printf("请输入“1”求该结点的双亲结点,输入“2”求该结点的左孩子,输入“3”求该结点的右孩子,输入“4”求该结点的左兄弟,输入“5”求该结点的右兄弟..\n\n"); scanf("%d",&i); getchar(); switch(i) { case 1: { if(Parent(T,value)==NULL) printf("该结点没有双亲结点。\n"); else printf("该结点的双亲结点为:%c\n\n",Parent(T,value));break; } case 2: { if(LeftChild(T,value)==NULL) printf("该结点没有左孩子结点。\n"); else printf("该结点的左孩子结点为:%c\n\n",LeftChild(T,value));break; } case 3: { if(RightChild(T,value)==NULL) printf("该结点没有右孩子结点。\n"); else printf("该结点的右孩子结点为:%c\n\n",RightChild(T,value));break; } case 4: { if(LeftSibling(T,value)==NULL) printf("该结点没有左兄弟。\n"); else printf("该结点的左兄弟为:%c\n\n",LeftSibling(T,value)); break; } case 5: { if(RightSibling(T,value)==NULL) printf("该结点没有右兄弟。\n"); else printf("该结点的右兄弟为:%c\n\n",RightSibling(T,value)); break; } } printf("\n现在进行结点插入子树,请按照先序遍历的顺序输入二叉树C,注意该二叉树没有右子树!\n"); InitBiTree(C); CreateBiTree(C); getchar(); printf("\n请输入您需要插入子树的结点:\n"); scanf("%c",&a); getchar(); p=Point(T,a); printf("\n输入0示插入C为%c结点的左子树而该结点原来的左子树变为c的右子树...",a); printf("\n输入1示插入C为%c结点的右子树而该结点原来的左子树变为c的右子树,请选择...\n",a); scanf("%d", &LR); getchar(); j= InsertChild(T, p, LR, C); if(j==0) { printf("插入失败!\n"); } else { printf("插入成功!该新二叉树的先序遍历为:"); PreOrderTraverse(T, visit); } printf("\n\n进行删除操作,请输入需要删除左子树或者右子树的结点:"); scanf("%c",&a); getchar(); p=Point(T,a); printf("\n输入 0 表示删除%c结点的左子树, 1 表示删除%c结点的右子树,请选择...\n",a); scanf("%d", &LR); getchar(); j = DeleteChild(T, p, LR); if(j==0) { printf("删除失败!\n"); } else { printf("删除成功!该新二叉树的先序遍历为:"); PreOrderTraverse(T, visit); } DestroyTree(T); if (!T) printf("\n树已被成功销毁!程序执行完毕,请按回车键\n"); else printf("\n树销毁不成功!程序执行完毕,请按回车键\n"); getchar(); for(i=1;i<=4;++i) printf("\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ****************************** 感谢使用 *****************************\n"); printf(" ****************************** * * *****************************\n"); printf(" ****************************** 计科四班 *****************************\n"); printf(" ****************************** *****************************\n"); printf(" ******************************制作人:罗志权 *****************************\n"); printf(" ****************************** *****************************\n"); printf(" ******************************学号:3111005843*****************************\n"); printf(" ***************************** *****************************\n"); printf(" *****************************请按回车键退出程序****************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); printf(" ***************************************************************************\n"); getchar(); return OK; } 4.程序清单(计算机打印),输入的数据及各基本操作的测试结果; 開始: 第一步:手动创建二叉树: 第二步:选择操作,这里选择查看深度: 第三步:选择遍历方法,这里选择中序遍历: 第五步:替换某个结点: 第六步:求该结点的邻近结点,这里选择右孩子: 第七步:插入子树C到e结点作为e结点的左子树: 第八步:删除结点的左子树或者右子树: 程序执行完毕: 显示作者: 六.实验总结和体会。 抽象数据类型是模块化思想的发展,有助于我们从更抽象的高度去讨论算法和数据结构的问题。通过这次实验,我对二叉树的抽象数据类型更加了解和熟悉,我们只需关心它的逻辑特征而不需要了解它的存储方式。数据结构是每个程序员的必修课,但是我们还要学的还有很多很多,因为在设计程序的时候会遇到很多的BUG,这些BUG都是要靠自己慢慢去了解慢慢去调试才能解决的。而且现在计算机技术发展迅速,我们要学的可以说是无穷无尽的。 THANKS !!! 致力为企业和个人提供合同协议,策划案计划书,学习课件等等 打造全网一站式需求 欢迎您的下载,资料仅供参考- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 广东工业大学 数据结构 二叉 课程设计
咨信网温馨提示:
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【丰****】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【丰****】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【丰****】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【丰****】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
关于本文