树的展示系统和二叉树的转换系统.docx
《树的展示系统和二叉树的转换系统.docx》由会员分享,可在线阅读,更多相关《树的展示系统和二叉树的转换系统.docx(34页珍藏版)》请在冰豆网上搜索。
树的展示系统和二叉树的转换系统
《数据结构课程设计》报告
课题名称:
树的展示系统和二叉树的转换系统
专业:
班级:
姓名:
指导教师:
成绩:
2011
年
12
月
30
日
目录
1前言-------------------------------------------------------------------------------------------3
2需求分析--------------------------------------------------------------------------------------5
3概要设计(特殊功能)---------------------------------------------5
4详细设计---------------------------------------------------------5
5源代码及调试-----------------------------------------------------5
6用户使用说明及测试结果-------------------------------------------19
7总结及分析-------------------------------------------------------26
8参考文献-------------------------------------------------------------------------------------27
1.前言
1.1课题简介
本次我们选择的课程设计的题目名称是:
树的展示系统和二叉树的转换系统,这一题目。
目的是为了,能让自己的编程得到锻炼,熟悉各种数据结构的性质,并学会合理地选择适当的数据结构来让编出的程序更富有健壮性。
这一题目,要实现,树的生成,树的显示,二叉树的显示,二叉树的遍历。
预期希望能够实现上述基本功能。
1.2方案及其论证
1.2.1系统平台需求
1.系统开发平台
操作系统:
Windowsxp系列
开发工具:
VisualC++6.0
2.开发环境介绍
本次课程设计我们采用的是vc++6.0的编程环境.VC++是微软公司开发的一个IDE(集成开发环境),换句话说,就是使用c++的一个开发平台.有些软件就是这个编出来的...
vc++是Windows平台上的C++编程环境,学习VC要了解很多Windows平台的特性并且还要掌握MFC、ATL、COM等的知识,难度比较大。
Windows下编程需要了解Windows的消息机制以及回调(callback)函数的原理;MFC是Win32API的包装类,需要理解文档视图类的结构,窗口类的结构,消息流向等等;COM是代码共享的二进制标准,需要掌握其基本原理等等。
VC作为一个主流的开发平台一直深受编程爱好者的喜爱,但是很多人却对它的入门感到难于上青天,究其原因主要是大家对他错误的认识造成的,严格的来说VC++不是门语言,虽然它和C++之间有密切的关系,如果形象点比喻的话,可以C++看作为一种”工业标准”,而VC++则是某种操作系统平台下的”厂商标准”,而”厂商标准”是在遵循”工业标准”的前提下扩展而来的。
VC++应用程序的开发主要有两种模式,一种是WINAPI方式,另一种则是MFC方式,传统的WINAPI开发方式比较繁琐,而MFC则是对WINAPI再次封装,所以MFC相对于WINAPI开发更具备效率优势,但为了对WINDOWS开发有一个较为全面细致的认识,笔者在这里还是以讲解WINAPI的相关内容为主线。
要想学习好VC必须具备良好的C/C++的基础,必要的英语阅读能力也是必不可少的,因为大量的技术文档多以英文形式发布。
vc6.0的优点是界面简洁,占用资源少,操作方便。
系统功能结构主要有四块:
树的生成,树的显示,二叉树的显示,二叉树的遍历实现技术:
运用这个学期学过的数据结构的知识,与之前的知识相结合,在vc++6.0中进行编程实现。
1.2.2设计进度安排:
12.26号(星期一),地点:
机房,布置任务,上网查找资料,分组和分工,选择课题,和老师沟通,确认课题的目标。
学习课设范例,了解马氏编程模板的特点与风格。
了解变量定义的细节。
了解工作量和难度的要求。
地点:
机房开始整体构建,界面设计,功能设计。
马春江
12.27号(星期二),上午:
地点:
机房,8:
10到。
开始编程,按照分工,自己完成自己的一部分。
下午:
地点:
机房继续编程,实现各种细节。
梅琴
12.28号(星期三),上午:
地点:
寝室。
各个组长开始通过电子邮件收集小组成员的作品,进行集中联调。
下午:
地点:
寝室。
小组成员在组长的计算机上观摩和讨论。
改进一些错误或者不完善的地方。
各小组组长。
12.29号(星期四),上午:
地点;寝室。
小组分工书写开发报告。
每个人需要提交一份报告,小组还有另外一个小组开发报告。
另外有一个宣讲的PPT。
小组成员交流,互相听取个人报告,小组开发报告定稿。
各小组组长
12.30号(星期五),上午:
地点:
寝室。
组长为中心。
做一些修改或验收性完善。
下午:
地点:
机房。
2:
30到。
4:
30之前验收完毕。
之后的算迟交。
马老师、梅老师。
12.31号(星期六),老师批改报告,查阅程序内部编码,电话或qq访谈个别小组成员或组长。
结束批改,形成初步成绩单。
马老师、梅老师。
2需求分析
所谓"需求分析",是指对要解决的问题进行详细的分析,弄清楚问题的要求,包括需要输入什么数据,要得到什么结果,最后应输出什么。
可以说,在软件工程当中的“需求分析”就是确定要计算机“做什么”。
1树的生成(存储结构:
双指针链表(儿子兄弟挂法))
2树的显示
3树的层次遍历
4二叉树的显示
5二叉树的遍历
3概要设计(特殊功能)
概要设计的主要任务是把需求分析得到的DFD转换为软件结构和数据结构。
设计软件结构的具体任务是:
将一个复杂系统按功能进行模块划分、建立模块的层次结构及调用关系、确定模块间的接口及人机界面等。
数据结构设计包括数据特征的描述、确定数据的结构特性、以及数据库的设计。
显然,概要设计建立的是目标系统的逻辑模型,与计算机无关。
本程序的目的就是实现树的生成,树的显示,树的层次遍历,二叉树的遍历等基本功能,具体函数见第五部分的源程序……
4详细设计
详细设计是软件工程中软件开发的一个步骤,就是对概要设计的一个细化,就是详细设计每个模块实现算法,所需的局部结构。
我在这个程序中用的存储结构为:
双指针链表,主要是通过儿子、兄弟挂链法来来建立一棵树,建立树的时候我采用的是3种输入,一,内部预置;二,键盘输入;三,文件读入。
3种输入的形式是字符串型的,用的是广义表形式,如:
a(b,c(d,e),f);通过链表遍历方式的不同,我分别输出了该树的树的显示(广义表的形式)、树的显示(凹入表示法)、树的层次遍历、以及该树转换成的二叉树的显示(凹入表示法)、二叉树的显示(广义表的形式)、二叉树的先根遍历、二叉树的中根遍历、二叉树的后根遍历、二叉树的层次遍历。
最后我通过释放结点,进行销毁这棵树的操作。
5源代码及调试
5.1源代码
/****************
**********
2.树的展示系统和二叉树的转换系统
**********************/
#include"iostream.h"
#include"stdlib.h"
#include"windows.h"
#include"string.h"
#include"stdio.h"
#defineMaxnum30
typedefstructBTree{
chardata;
structBTree*lchild,*rchild;
}BTNode;
voidMenu(){
cout<cout<<"=>>==>>==>>==>>==>>==>>==>>==>>==>>==>>==>>==>>="<cout<<"<<程>>==<<序>>==<<相>>==<<关>>==<<信>>==<<息>>"<cout<<"────────────────────────"<cout<<"程序功能:
│树的展示系统和二叉树的转换系统"<cout<<"─────┼──────────────────"<cout<<"指导教师:
│马春江、梅琴"<cout<<""<cout<<"~~~~~~~~1:
树的生成"<cout<<"~~~~~~~~2:
树的显示(广义表的形式)"<cout<<"~~~~~~~~3:
树的显示(凹入表示法)"<cout<<"~~~~~~~~4:
树的层次遍历"<cout<<"~~~~~~~~5:
二叉树的显示(凹入表示法)"<cout<<"~~~~~~~~6:
二叉树的显示(广义表的形式)"<cout<<"~~~~~~~~7:
二叉树的先根遍历"<cout<<"~~~~~~~~8:
二叉树的中根遍历"<cout<<"~~~~~~~~9:
二叉树的后根遍历"<cout<<"~~~~~~~~10:
二叉树的层次遍历"<cout<<"~~~~~~~~11:
判断树是否为空"<cout<<"~~~~~~~~12:
销毁整棵树"<cout<<"~~~~~~~~0:
退出系统"<cout<<"==>>====>>====>>====>>====>>====>>====>>====>>=="<}
voidShow1(BTNode*bt){//凹入表示法输出树
FILE*fp;
BTNode*St[Maxnum],*p;
intS[Maxnum],top=-1,n,i,width=4;
if((fp=fopen("树(凹入表示法).txt","at+"))==NULL)
{
printf("Cannotopenfilestrikeanykeyexit!
");
getchar();
exit
(1);
}
if(bt!
=NULL){
top++;
St[top]=bt;//根结点入栈
S[top]=width;
while(top>-1){
p=St[top];
n=S[top];
for(i=1;i<=n;i++){//n为显示长宽
cout<<"";
fputc('',fp);
}
cout<data<<"──"<fputc(p->data,fp);
fputc('',fp);
fputc('\n',fp);
top--;
if(p->rchild!
=NULL){
top++;
St[top]=p->rchild;
S[top]=n;//表示右子树
}
if(p->lchild!
=NULL){
top++;
St[top]=p->lchild;
S[top]=n+width;//表示左子树
}
}
}
fputc('\n',fp);
fclose(fp);
}
//生成树
voidCreateBTree(BTNode*&bt,char*str){//树的存储(儿子兄弟挂链法)
BTNode*St[Maxnum],*p=NULL;
inttop=-1,k,j=0;
charch;
bt=NULL;
ch=str[j];
while(ch!
='\0'){
switch(ch){
case'(':
//左儿子
top++;
St[top]=p;
k=1;
break;
case')':
if(k==0)
{
top--;
}
k=0;
break;
case',':
//右儿子
if(k==0){
k=2;
break;
}
else{
top++;
St[top]=(BTNode*)malloc(sizeof(BTNode));
St[top]=p;
k=2;
break;
}
default:
p=(BTNode*)malloc(sizeof(BTNode));
p->data=ch;
p->lchild=p->rchild=NULL;
if(bt==NULL){
bt=p;
}
else{
switch(k){
case1:
St[top]->lchild=p;
cout<<"将"<data<<"挂在"<data<<"的儿子链上"<cout<<"此时构建的树为:
"<Show1(bt);
break;
case2:
St[top]->rchild=p;
cout<<"将"<data<<"挂在"<data<<"的兄弟链上"<cout<<"此时构建的树为:
"<Show1(bt);
top--;break;
}
}
}
j++;
ch=str[j];
}
}
voidLevelTree(BTNode*point){//树的层次遍历
BTNode*p;
BTNode*que[Maxnum];//定义环状队列1
BTNode*St[Maxnum];//定义环状队列2
intfront,rear,front1,rear1;
front=rear=-1;
front1=rear1=-1;
rear++;
que[rear]=point;//根结点指针入队1
while(front!
=rear){
front=(front+1)%Maxnum;
p=que[front];
cout<data;
if(p->rchild!
=NULL){
rear=(rear+1)%Maxnum;
que[rear]=p->rchild;
}
if(p->lchild!
=NULL){
rear1=(rear1+1)%Maxnum;//左儿子入队一
St[rear1]=p->lchild;
}
if(p->rchild==NULL){
if(front1!
=rear1){//出对一进队二
rear=(rear+1)%Maxnum;
front1=(front1+1)%Maxnum;
que[rear]=St[front1];
}
}
}
}
voidShow(BTNode*tree){//树的显示(广义表表示法)
FILE*fp;
BTNode*searchp1;
BTNode*searchp[30],*S[30];
inti=0,j=0,k=0;
if((fp=fopen("树(广义表表示).txt","at+"))==NULL)
{
printf("Cannotopenfilestrikeanykeyexit!
");
getchar();
exit
(1);
}
searchp[i]=tree;
searchp1=tree;
while(i>=0){
while(searchp1!
=NULL){
cout<data;
fputc(searchp1->data,fp);
if(searchp1->rchild!
=NULL){
i++;
searchp[i]=searchp1->rchild;
}
if(searchp1->lchild!
=NULL){
cout<<"(";
fputc('(',fp);
j++;
k++;
S[j]=searchp1;
}
if(searchp1->rchild==NULL&&searchp1->lchild==NULL&&k!
=0){
cout<<")";
fputc(')',fp);
while(j>1&&S[j]->rchild==NULL){
cout<<")";
fputc(')',fp);
j--;
}
}
searchp1=searchp1->lchild;
}
searchp1=searchp[i];
if(i!
=0){
cout<<",";
fputc(',',fp);
}
i--;
}
fputc('\n',fp);
fclose(fp);
}
voidDispBTree(BTNode*bt){//显示二叉树(括号表示法)
FILE*fp;
if((fp=fopen("二叉树(括号表示法).txt","at+"))==NULL)
{
printf("Cannotopenfilestrikeanykeyexit!
");
getchar();
exit
(1);
}
if(bt!
=NULL){
cout<data;
fputc(bt->data,fp);
if(bt->lchild!
=NULL||bt->rchild!
=NULL){
cout<<"(";
fputc('(',fp);
DispBTree(bt->lchild);
if(bt->rchild!
=NULL){
cout<<",";
fputc(',',fp);
}
DispBTree(bt->rchild);
cout<<")";
fputc(')',fp);
}
}
fputc('\n',fp);
fclose(fp);
}
voidDispBTree1(BTNode*bt){//凹入表示法输出二叉树
FILE*fp;
if((fp=fopen("二叉树(凹入表示法).txt","at+"))==NULL)
{
printf("Cannotopenfilestrikeanykeyexit!
");
getchar();
exit
(1);
}
BTNode*St[Maxnum],*p;
intS[Maxnum][2],top=-1,n,i,width=4;
chartype;
if(bt!
=NULL){
top++;
St[top]=bt;//根结点入栈
S[top][0]=width;
S[top][1]=2;//2表示的是根
while(top>-1){
p=St[top];
n=S[top][0];
switch(S[top][1]){
case0:
type='L';
break;
case1:
type='R';
break;
case2:
type='B';
break;
}
for(i=1;i<=n;i++){//n为显示长宽
cout<<"";
fputc('',fp);
}
cout<data<<"("<fputc(p->data,fp);
fputc('(',fp);
fputc(type,fp);
fputc(')',fp);
top--;
if(p->rchild!
=NULL){
top++;
St[top]=p->rchild;
S[top][0]=n+width;
S[top][1]=1;//1表示右子树
}
if(p->lchild!
=NULL){
top++;
St[top]=p->lchild;
S[top][0]=n+width;
S[top][1]=0;//0表示左子树
}
}
}
fputc('\n',fp);
fclose(fp);
}
voidpreorder(BTNode*point){//二叉树的先根遍历
if(point!
=NULL){
cout<data;
preorder(point->lchild);
preorder(point->rchild);
}
}
voidinorder(BTNode*point){//二叉树的中根遍历
if(point!
=NULL){
preorder(point->lchild);
cout<data;
preorder(point->rchild);
}
}
voidpostorder(BTNode*point){//二叉树的后根遍历
if(point!
=NULL){
preorder(point->lchild);
preorder(point->rchild);
cout<data;
}
}
voidLevelOrder(BTNode*point){//二叉树的层次遍历
BTNode*p;
BTNode*que[Maxnum];//定义环状队列
intfront,rear;
front=rear=-1;
rear++;
que[rear]=point;
while(front!
=rear){
front=(front+1)%Maxnum;
p=que[front];
cout<data;
if(p->lchild!
=NULL){
rear=(rear+1)%Maxnum;
que[rear]=p->lchild;
}
if