12数据结构课程设计报告.docx
- 文档编号:10031663
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:43
- 大小:361.75KB
12数据结构课程设计报告.docx
《12数据结构课程设计报告.docx》由会员分享,可在线阅读,更多相关《12数据结构课程设计报告.docx(43页珍藏版)》请在冰点文库上搜索。
12数据结构课程设计报告
算法与数据结构课程设计报告
系(院):
计算机科学学院
专业班级:
教育技术学1001班
姓名:
宋佳
学号:
201003901
指导教师:
詹泽梅
设计时间:
2012.6.16-2012.6.24
设计地点:
4号楼2号机房
《算法与数据结构》课程设计任务书
班级:
教育技术11001
课程设计题目:
图的基本操作及应用
数据结构课程设计是在学完数据结构课程之后的实践教学环节。
本实践教学是培养学生数据抽象能力,进行复杂程序设计的训练过程。
要求学生能对所涉及问题选择合适的数据结构、存储结构及算法,并编写出结构清楚且正确易读的程序,提高程序设计基本技能和技巧。
一.设计目的
1.提高数据抽象能力。
根据实际问题,能利用数据结构理论课中所学到的知识选择合适的逻辑结构以及存储结构,并设计出有效解决问题的算法。
2.提高程序设计和调试能力。
学生通过上机实习,验证自己设计的算法的正确性。
学会有效利用基本调试方法,迅速找出程序代码中的错误并且修改。
3.初步了解开发过程中问题分析、整体设计、程序编码、测试等基本方法和技能。
二.设计任务
设计一个基于DOS菜单的应用程序。
要利用多级菜单实现各种功能。
内容如下:
1.无向图的基本操作及应用
1创建无向图的邻接矩阵
2创建无向图的邻接表
3无向图的深度优先遍历
4无向图的广度优先遍历
2.有向图的基本操作及应用
1创建有向图的邻接矩阵
2创建有向图的邻接表
3拓扑排序
3.无向网的基本操作及应用
1创建无向网的邻接矩阵
2创建无向网的邻接表
3求最小生成树
4.有向网的基本操作及应用
1创建有向网的邻接矩阵
2创建有向网的邻接表
3关键路径
4单源最短路径
三.设计指导
第一步:
根据设计任务,设计DOS菜单。
第二步:
设计菜单(c语言)
#include
voidShowMainMenu(){
printf("\n");
printf("**************图的基本操作及应用***************\n");
printf("*1无向图的基本操作及应用*\n");
printf("*2有向图的基本操作及应用*\n");
printf("*3无向网的基本操作及应用*\n");
printf("*4有向网的基本操作及应用*\n");
printf("*5退出\n");
printf("***********************************************\n");
}
voidUDG(){
intn;
do{
printf("\n");
printf("**************无向图的基本操作及应用***************\n");
printf("*1创建无向图的邻接矩阵*\n");
printf("*2创建无向图的邻接表*\n");
printf("*3无向图的深度优先遍历*\n");
printf("*4无向图的广度优先遍历*\n");
printf("*5退出\n");
printf("***********************************\n");
printf("请选择:
");
scanf("%d",&n);
switch(n){
case1:
printf("----------wait-------");break;
case2:
printf("----------wait-------");break;
case3:
printf("----------wait-------");break;
case4:
printf("----------wait-------");break;
case5:
break;
default:
printf("ERROR!
");
}
}while(n!
=5);
}
voidDG(){
intn;
do{
printf("\n");
printf("**************有向图的基本操作及应用***************\n");
printf("*1创建有向图的邻接矩阵*\n");
printf("*2创建有向图的邻接表*\n");
printf("*3拓扑排序*\n");
printf("*4退出*\n");
printf("*******************************\n");
printf("请选择:
");
scanf("%d",&n);
switch(n){
case1:
printf("--------wait-------");break;
case2:
printf("--------wait-------");break;
case3:
printf("--------wait-------");break;
case4:
break;
default:
printf("ERROR!
");
}
}while(n!
=4);
}
voidUDN(){
intn;
do{
printf("\n");
printf("**************无向网的基本操作及***\n");
printf("*1创建无向网的邻接矩阵*\n");
printf("*2创建无向网的邻接表*\n");
printf("*3Prim算法求最小生成树*\n");
printf("*4kraskal算法求最小生成树*\n");
printf("*5退出\n");
printf("*************************************\n");
printf("请选择:
");
scanf("%d",&n);
switch(n){
case1:
printf("---------wait-------");break;
case2:
printf("-------wait-------");break;
case3:
printf("---------wait-------");break;
case4:
printf("---------wait-------");break;
case5:
break;
default:
printf("ERROR!
");
}
}while(n!
=5);
}
voidDN(){
intn;
do{
printf("\n");
printf("**************有向网的基本操作****\n");
printf("*1创建有向网的邻接矩阵*\n");
printf("*2创建有向网的邻接表*\n");
printf("*3关键路径*\n");
printf("*4单源顶点最短路径问题*\n");
printf("*5退出\n");
printf("***********************************\n");
printf("请选择:
");
scanf("%d",&n);
switch(n){
case1:
printf("---------wait-------");break;
case2:
printf("---------wait-------");break;
case3:
printf("---------wait-------");break;
case4:
printf("---------wait-------");break;
case5:
break;
default:
printf("ERROR!
");
}
}while(n!
=5);
}
voidmain(){
intn;
do{
ShowMainMenu();
printf("请选择:
");
scanf("%d",&n);
switch(n){
case1:
UDG();break;
case2:
DG();break;
case3:
UDN();break;
case4:
DN();break;
case5:
break;
default:
printf("ERROR!
");break;
}
}while(n!
=5);
}
第三步:
添加功能函数。
在主程序的合适位置添加相应的函数实现各功能(提示:
语句printf(“-------wait---------”)所在位置)。
四.成绩评定
●实习报告(文字不得少于4000字)
一、设计方案;
二、实现过程;
三、实现代码;
四、测试;
五、结论;
六、难点与收获。
●程序实现
1.程序运行正确,无编译错误,无逻辑错误;
2.在第一条的基础上,任务完成的越多,成绩等级越高。
●成绩由三部分组成:
平时考核(20%)、程序实现(50%)、实习报告(30%)
一、设计方案
由课程设计任务书,按照要求,需要设计有向图3、有向网、无向图、无向网四种图,邻接矩阵、邻接表两种数据存储结构,共十六种基本操作及应用,三层以上的显示菜单。
图的操作中又包含有有关线性表、栈和队列的基本操作。
由于显示菜单已给出,剩下的只是把函数写入其中,而线性表、栈和队列的基本操作并不复杂,很容易实现,我们只有完成图的相关操作即可。
图的操作都是以两种存储结构为基础的,邻接矩阵存储结构和邻接表存储
结构,如四种图(有向图,有向网,无向图,无向网)的创建,其他的操作都是在四种图创建后才开始进行的。
所以,首先必须理解两种存储结构的定义。
图的邻接矩阵存储结构即图的数组表示法。
用两个数组分别存储数据元素(顶点)的信息和数据元素之间的关系(边或弧)的信息。
用邻接矩阵存储结构的图具有以下几点特征:
(一):
顶点数:
vexnum,边(弧)数:
arcnum,图的种类:
kind;
(二):
邻接矩阵:
arcs(1顶点关系类型:
adj2相关信息:
*info);
(三):
顶点向量(顶点名):
vexs[];
其优点是以二维数组表示有n个顶点的图时,需存放n顶点的信息和n*n个弧的信息存储量。
借助于邻接矩阵容易判定任意两个顶点之间是否有边或弧相连,并容易求各个顶点的度。
缺点其时间复杂度是O(n*n),例如,构造一个具有n个顶点和e条边的无向网的时间复杂度为O(n*n+e*n)。
图的邻接表存储结构是图的一种链式存储结构。
对图中的每个顶点建立一个单链表,每个结点有三个域组成,邻接点域adjvex(弧尾在邻接表链表中的位序),链域nextarc(下一条弧),数据域info(权值)。
还要建立一个邻接表链表,用以存放顶点名data和后继指针firstarc,表头结点以顺序结构的形式存储,便于随机访问任一顶点的单链表。
邻接表存储结构的优点在于其时间复杂度小。
除此之外,还有十字链表存储结构和多重链表存储结构。
由于,没有用到他们,故不再详细描述。
树的深度优先搜索遍历类似于树的先根遍历,是树的先根遍历的推广。
从图中的某个顶点出发,访问此顶点,然后依次从该顶点出发深度优先搜索遍历图,直至图中所有与该顶点有关的路径都被访问到;此时图中若还有顶点未被访问到,则另选图中的一个未被访问的顶点作为起始点,重述上述过程,直至所有顶点都被访问到。
广度优先搜索遍历类似于树的按层次遍历的过程。
以某个顶点为起始顶点,由近至远,依次访问和该顶点有路径相通的且路径长度为1,2,3,······的顶点。
当图中所有顶点都被访问到后,就完成了图的广度优先搜索遍历。
求无向网的最小生成树问题有两种算法:
Prima算法和Kruskal算法。
Prima算法是从网中的某个顶点出发,选择与该顶点有路径的所有顶点中路径最小的一条路径,从该最小路径的另一顶点出发,重复上述过程,直至图中所有顶点都被访问完成。
Kruskal算法是从网中找出所有路径最小的一条路径,记下已访问该路径的两个顶点,再次从图中找出剩下路径中的最小路径,重复上述过程,直至所有顶点都被访问完成,按访问的顺序依次输出各顶点,即构造了一棵最小生成树。
由某个集合上的一个偏序得到该集合的一个全序的操作就叫做拓扑排序。
拓扑排序主要有两个方面的操作:
(1)在有向图中选择一个没有前驱的顶点并输出;
(2)在图中删除该顶点和所有以它为尾的弧。
重复上述两步,直至全部顶点均已输出,就得到了一个拓扑有序序列。
求关键路径的算法如下:
输入e条弧,建立AOE网的存储结构;
从源点v0出发,令ve[0]=0,按拓扑有序求其余各顶点的最早发生时间。
如果得到的拓扑有序序列中的顶点个数小于网中的顶点数,则说明网中存在环,不能求关键路径,算法终止;否则执行第三步。
从汇点vn出发,令vl[n-1]=ve[n-1],按逆拓扑有序求其余各顶点的最迟发生时间vl[i];
根据各顶点的和值,求每条弧的最早开始时间e(s)和最迟开始时间e(s),若某条弧满足条件e(s)=l(s),则为关键活动。
从某个源点到其余各顶点的最短路径问题:
若从v到vi有弧,则D[i]为弧上的权值,否则D[i]为无穷大。
显然,长度为D[j]=Min{D[i]|vi属于V}的路径就是从v出发的长度最短的一条路径。
二、实现及测试过程
按照设计任务的要求,我先完成了存储结点、边、邻接矩阵、邻接表、队列、栈等储存结构体的设计。
其次是栈和队列的基本操作和实现,四种图的创建和显示,然后是基于两种存储结构的各种算法的现,最后是三层显示输出菜单。
测试样图:
三、实现代码
#include
#include
#include
#defineERROR0
#defineOK1
#defineINFINITYINT_MAX
#defineMAX_VERTEX_NUM21
#defineSTACK_INIT_SIZE100
#defineSTACKINCREAMENT10
typedefenum{DG,DN,UDG,UDN}GraphKind;
typedefstructArcCell{
intadj;
//infotype*info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedefstruct{
charvexs[MAX_VERTEX_NUM];
AdjMatrixarcs;
intvexnum,arcnum;
GraphKindkind;
}MGraph;//邻接矩阵
typedefstructArcNode{
intadjvex;
intquan;
structArcNode*nextarc;
}ArcNode,*AList;
typedefstructVNode{
chardata;
AListfirstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct{
AdjListvertices;
intvexnum,arcnum;
GraphKindkind;
}ALGraph;//邻接表
typedefstructQNode{
chardata;
structQNode*next;
}QNode,*QueuePre;
typedefstruct{
QueuePrefront;
QueuePrerear;
}LinkQueue;//队列
typedefstruct{
int*base;
int*top;
intstacksize;
}SqStack;//栈
typedefstruct{
charadjvex;
intlowcost;
}closedges[MAX_VERTEX_NUM];//求最小生成树中的辅助数组
intoption;
intvisited[MAX_VERTEX_NUM];//顶点访问标记数组
intindegree[MAX_VERTEX_NUM];//顶点入度记录数组
intve[MAX_VERTEX_NUM];//顶点权值记录数组
intSetGraphKind(MGraph&G,intoption){
switch(option){
case1:
G.kind=DG;break;
case2:
G.kind=DN;break;
case3:
G.kind=UDG;break;
case4:
G.kind=UDN;break;
default:
returnERROR;
}
returnOK;
}//邻接矩阵类型设置
intSetGraphKind(ALGraph&G,intoption){
switch(option){
case1:
G.kind=DG;break;
case2:
G.kind=DN;break;
case3:
G.kind=UDG;break;
case4:
G.kind=UDN;break;
default:
returnERROR;
}
returnOK;
}//邻接表类型设置
intLocateVex(MGraphG,charv){
intm;
for(m=1;m<=G.vexnum;m++){
if(G.vexs[m]==v)returnm;
}
returnERROR;
}//邻接矩阵顶点定位
intLocateVex(ALGraphG,charv){
intm;
for(m=1;m<=G.vexnum;m++){
if(G.vertices[m].data==v)returnm;
}
printf("您输入的顶点不存在");
returnERROR;
}//邻接表顶点定位
intInitQueue(LinkQueue&Q){
Q.front=Q.rear=(QueuePre)malloc(sizeof(QNode));
if(!
Q.front)returnERROR;
Q.front->next=NULL;
returnOK;
}//队列创建
intEnQueue(LinkQueue&Q,inte){
QueuePrep;
p=(QueuePre)malloc(sizeof(QNode));
if(!
p)returnOK;
p->data=e;p->next=NULL;
Q.rear->next=p;
Q.rear=p;
returnOK;
}//元素入队列
intDeQueue(LinkQueue&Q,int&e){
QueuePrep;
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;
}//元素出队列
intQueueEmpty(LinkQueueQ){
if(Q.front==Q.rear)
returnOK;
returnERROR;
}//判断队列是否为空
intInitStack(SqStack&S){
S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));
if(!
S.base)returnERROR;
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
returnOK;
}//栈创建
intPush(SqStack&S,inte){
if(S.top-S.base>=S.stacksize){
S.base=(int*)realloc(S.base,(S.stacksize+STACKINCREAMENT)*sizeof(int));
if(!
S.base)returnERROR;
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREAMENT;
}
*S.top++=e;
returnOK;
}//元素入栈
intPop(SqStack&S,int&e){
if(S.top==S.base)returnERROR;
e=*--S.top;
returnOK;
}//元素出栈
intStackEmpty(SqStackS){
if(S.top==S.base)returnOK;
returnERROR;
}//判断栈是否为空
intCreatGraph(MGraph&G){
inti,j,k,w;charx,y;
if(!
SetGraphKind(G,option)){printf("对图类型的设置失败");returnERROR;}
printf("邻接矩阵:
请输入定点的个数、弧的个数:
");
scanf("%d%d",&G.vexnum,&G.arcnum);
if(G.vexnum>20){
printf("您输入的顶点个数超过最大值");
returnERROR;
}
printf("请输入%d个顶点\n",G.vexnum);
for(i=1;i<=G.vexnum;++i){fflush(stdin);scanf("%c",&G.vexs[i]);}
if(G.kind==DG||G.kind==UDG){
for(i=1;i<=G.vexnum;i++)
for(j=1;j<=G.vexnum;j++)
G.arcs[i][j].adj=0;
if(G.kind==DG){
printf("请输入有向图的两个相邻的顶点
\n");
for(k=1;k<=G.arcnum;k++){fflush(stdin);
scanf("%c%c",&x,&y);
i=LocateVex(G,x);j=LocateVex(G,y);
G.arcs[i][j].adj=1;
}
}
else{
printf("请输入无向图的两个相邻的顶点(x,y):
\n");
for(k=1;k<=G.arcnum;k++){fflush(stdin);
scanf("%c%c",&x,&y);
i=LocateVex(G,x);j=LocateVex(G,y);
G.arcs[i][j].adj=1
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 12 数据结构 课程设计 报告