程道雷数据结构课程设计课程设计书.docx

上传人:b****3 文档编号:5485252 上传时间:2022-12-17 格式:DOCX 页数:26 大小:417.21KB
下载 相关 举报
程道雷数据结构课程设计课程设计书.docx_第1页
第1页 / 共26页
程道雷数据结构课程设计课程设计书.docx_第2页
第2页 / 共26页
程道雷数据结构课程设计课程设计书.docx_第3页
第3页 / 共26页
程道雷数据结构课程设计课程设计书.docx_第4页
第4页 / 共26页
程道雷数据结构课程设计课程设计书.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

程道雷数据结构课程设计课程设计书.docx

《程道雷数据结构课程设计课程设计书.docx》由会员分享,可在线阅读,更多相关《程道雷数据结构课程设计课程设计书.docx(26页珍藏版)》请在冰豆网上搜索。

程道雷数据结构课程设计课程设计书.docx

程道雷数据结构课程设计课程设计书

课程设计(论文)任务书

软件学院软件工程+电子商务2009专业1班

一、课程设计(论文)题目有向图

二、课程设计(论文)工作自2010年12月27日起至2011年1月2日止

三、课程设计(论文)地点:

创新大楼实训中心

四、课程设计(论文)内容要求:

1.本课程设计的目的

(1)巩固和加深对数据结构基本知识的理解,提高综合运用课程知识的能力。

(2)使学生掌握软件设计的基本内容和设计方法,并培养学生进行规范化软

件设计的能力。

(3)使学生掌握使用各种计算机资料和有关参考资料,提高学生进行程序设

计的基本能力。

2.课程设计的任务及要求

1)基本要求:

(1)对系统进行功能模块分析、控制模块分析;

(2)系统设计要能完成题目所要求的功能;

(3)编程简练,可用,尽可能的使系统的功能更加完善和全面;

(4)说明书、流程图要清楚;

(5)提高学生的论文写作能力;

(6)特别要求自己独立完成;

2)创新要求:

在基本要求达到后,可进行创新设计,如改善算法性能、友好的人机界面。

3)课程设计论文编写要求

(1)要按照书稿的规格打印与写课程设计论文

(2)论文包括目录、正文、小结、参考文献、附录等

(3)课程设计论文装订按学校的统一要求完成

 

4)课程设计进度安排

内容天数地点

构思及收集资料1图书馆

编码与调试3实验室

撰写论文1图书馆、实验室

学生签名:

2011年1月3日

课程设计(论文)评审意见

(1)基本算法(20分):

优( )、良( )、中( )、一般( )、差( );

(2)设计分析 (20分):

优( )、良( )、中( )、一般( )、差( );

(3)调试分析 (20分):

优( )、良( )、中( )、一般( )、差( );

(4)论文内容 (20分):

优( )、良( )、中( )、一般( )、差( );

(5)答辩分析 (20分):

优( )、良( )、中( )、一般( )、差( );

(6)格式规范性及考勤是否降等级:

是()、否( )

评阅人:

职称:

讲师

2011年1月4日

目录

一、需求分析4

1.背景4

2、功能原理4

3、功能要求。

5

二、概要设计6

1、介绍使用的数据结构及其抽象数据类型的定义6

2、设计的整体框架9

三、详细设计10

1、图的结构10

2、各个方法10

四、调试分析及测试17

五、个人工作及创新22

附录24

一、需求分析

1.背景

本设计主要是对有向图的所有操作的一个叙述,因为我个人比较喜欢图论,而且对图论有过一定的深入的,所以操作起来更得心应手,而且图论在实际生活中是相当有用的。

图论是一门新兴的学科,它最早起源于对民间流传的一些数学难题的研究,比如迷宫问题、博奕间题和行走路线等,具有代表性的是瑞士数学家Euler于1736年解决的哥尼斯堡七桥问题。

20世纪30年代以后,随着运筹学,计算机和通讯网络等方面许多离散性问题的出现,图论得到了快速的发展。

如今图论在计算机科学、交通管理等许多领域起着越来越重要的作用,例如:

(1)、连通性与计算机网络、交通网络等的可靠性与健壮性息息相关;

(2)、欧拉图可用于解决一笔画问题、中国邮递员问题等,哈密顿图可用于解决哈密顿游戏,旅行售货员等问题;

(3)、树型结构作为一种重要的数据结构在计算机领域中有着广泛的应用,如哈夫曼编码,二叉排序等;

(4)、匹配与管理联系更紧密些,主要用于解决人员分配、实现最优安排等;

(5)、最后,关键路径和最短路径在交通网络、工程生产等的优化配置方面应用广泛,其主要目的在于节约资源,加快进度等。

然而这些用用途都是基于对图的遍历,其中深度优先遍历,和广度优先遍历是最为实用的,这些用途上基本都用了这些方法,就拿最短路来说,其中的:

ShortestPathFasterAlgorithm算法,便是利用广度优先搜索来写的。

2、功能原理

(1)、图的创建是借助于有向矩阵,这里创建的是一个有向图。

(2)、深度优先遍历借助于递归的实现。

(3)、广度优先遍历借助于队列的实现。

(4)、添加点和删除点都借助于标记点在不在图内。

(5)、添加边和删除边都是将边的值赋为1和0。

(6)、查找临接点就是遍历了。

(7)、输出图也是个遍历的过程。

(8)、其他的功能不用方法,直接实现。

3、功能要求。

(1)、菜单

(2)、创建图

(3)、销毁图

(4)、添加结点

(5)、删除结点

(6)、添加边

(7)、深度优先遍历

(8)、广度优先遍历

(9)、查找结点的位置和值

(10)、对图中的结点赋值

(11)、查找某结点的第一个邻接点

(12)、删除边

(13)、查找某结点的相对它第一个邻接点的下一个邻接点

(14)、以邻接矩阵输出图

(15)、退出系统

二、概要设计

1、介绍使用的数据结构及其抽象数据类型的定义

(1)、图的介绍

(2)、图的抽象数据类型

2、设计的整体框架

程序以main方法为入口,第一个必须完成图的创建操作,因为刚开始只是一个空图而已,然后就进入别的操作,操作主要是通过switch来进行相应的选择,让输入的操作表示符和相应的操作一一对应。

三、详细设计

1、图的结构

structG{///图的结构

charvec[ma];//表示图的字母

intvalue[ma];//结点的权值

intmap[ma][ma];//表示图的边

intv;//图的结点数

intedge;//数的边数

intindeep[ma];//点的入度

intoutdeep[ma];//点的出度

intinG[ma];

};

intFind(GL,charnum)//寻找点的下标

{ff(i,1,L.v)

{

if(!

L.inG[i])continue;

if(L.vec[i]==num)returni;

}

return0;

}

voidintial(G&L)

{//对图的初始化

ff(i,1,L.v)ff(j,1,L.v)L.map[i][j]=0;//边全为0,表示无边

ff(j,1,L.v)L.indeep[j]=0,L.outdeep[j]=0;

//边的入度出度全为0

clear_(L.inG,0);//所有的点不在图内

}

2、各个方法

(1)、销毁图

voidDestroyGraph(G&L)//销毁图

{

intial(L);//deleteL;

}

(2)、创建图

intCreatGraph(G&L)//创图

{

cout<<"输入点数和边数用空格隔开"<

cin>>L.v>>L.edge;

intial(L);

ff(j,1,L.v)L.value[j]=num[j];

cout<<"请输入相应的点"<

ff(i,1,L.v)

{

cin>>L.vec[i];

L.inG[i]=1;

}

cout<<"请输入每条边(每条边有两";

cout<<"个字母表示结点中间用空格隔开)"<

ff(i,1,L.edge)

{

cout<<"第"<

cin>>aa>>bb;

intx=Find(L,aa);

inty=Find(L,bb);

L.outdeep[x]++;L.indeep[y]++;

L.map[x][y]=1;

}

return1;

}

(3)、用矩阵的形式输出图

voidoutput(GL)//13

{//用矩阵的形式输出图

cout<<"结果为:

"<

ff(i,1,L.v)//只输出在图中的点

if(L.inG[i])

cout<<""<

cout<

intk;

ff(i,1,L.v)

{//按顺序找到第一个在图中的点

if(L.inG[i]){k=i;break;}//if()

}

ff(i,k,L.v)

{if(L.inG[i])

cout<

ff(j,k,L.v)

if(L.inG[j])

cout<

cout<

}

}

(4)、查找图中一个点的邻接点

charFirstAdjVex(GL,charv)//?

?

?

?

?

{//查找图中一个点的邻接点

intt=0;

intk=0;

k=Find(L,v);//查到该点的下标

if(k==0)return'0';

ff(i,1,L.v)

{//查这个点为出点,和这个点相邻的点

if(!

L.inG[i])continue;

if(L.map[k][i]==1)

{t=i;break;};//查到的话就记录下来

}

if(t==0)return'0';

elsereturnL.vec[t];//有则返回相应的点的字符,无则返回0

}

(5)、查找图中一个点相对第一个邻接点的下一个邻接点

charNextAdjVex(GL,charnei,charyou)//11

{//查找图中一个点相对第一个邻接点的下一个邻接点,无返回0,

//有返回该点的字符

intt=0;inttt=0;

tt=Find(L,you);//查找这个点的位置

ff(i,1,L.v)

{//查找要求的点

if(!

L.inG[i])continue;

if(L.vec[i]==nei)continue;

if(L.map[tt][i]==1){t=i;break;}

}

if(t)returnL.vec[t];

elsereturn'0';

}

(6)、广度优先遍历

voidBFSTraverse(intst,GL)//?

?

?

?

?

?

{/*

先将第一个点放入队列中,再将他的儿子全部放队列中,

然后又从第一个儿子开始,把他们的儿子全部放到队列中,

…………

这样下去,就可以把图遍历完全了

*/

queueque;

que.push(st);

sign[st]=1;

while(!

que.empty())

{

intu=que.front();

que.pop();//出队

cout<

//输出当前的点

ff(i,1,L.v)

{//不在图中的点过掉

if(!

L.inG[i])continue;

if(sign[i])continue;

//搜过的点过掉

if(L.map[u][i])//如果一个点和下搜的点有边的点

sign[i]=1,que.push(i);

}

}

}

(7)、深度优先搜索

voidDFSTraverse(intid,GL)

{

if(sign[id])return;//if(L.visit[id])return;

cout<

sign[id]=1;

ff(i,1,L.v)

{//如果这个点在图中,且没有被搜过,

//而且和id有边,就搜此点,一直搜下去到最深

if(sign[i]||!

L.inG[i])continue;

if(L.map[id][i])DFSTraverse(i,L);

}

}

(8)、查找某点的信息

intLovateVex(GL,charv)

{//查找这个点的信息

ff(i,1,L.v)

{

if(!

L.inG[i])continue;

if(L.vec[i]==v)returni;

}

return0;

}

(9)、对点的操作

intLovateVex(GL,charv)

{//查找这个点的位置

ff(i,1,L.v)

{

if(!

L.inG[i])continue;

if(L.vec[i]==v)returni;

}

return0;

}

intPutVex(G&L,intval,charid)

{//给点赋值

intk;

k=Find(L,id);

L.value[k]=val;

}

intGetVex(G&L,charid)

{//获取一个点的字母

k=Find(L,id);

returnL.value[k];//=val;

}

intInserVex(G&L,chart)

{//插入一个点

L.v++;//点的个数加1

L.vec[L.v]=t;//放在最后一个下标

L.inG[L.v]=1;//标记在图中

cout<<"请输入所添加结点的值:

"<

intva;

cin>>va;

L.value[L.v]=va;

}

intDeleteVex(G&L,chart)

{intk=0;

k=Find(L,t);

if(k==0){cout<<"对不起,无此结点!

"<

L.inG[k]=0;//标记此点不在图中

L.indeep[k]=0;//入度出度为0

L.outdeep[k]=0;

ff(i,1,L.v)

{//删除和这个点相关的所有边

//if(L.map[i][k])

if(L.map[i][k])

L.outdeep[i]--;

if(L.map[k][i])

L.indeep[i]--;

L.map[i][k]=0;

L.map[k][i]=0;

}

return1;

}

(10)、对边的操作

intInsertArc(G&L,chara,charb)

{//插入边

intid_a;

intid_b;

ff(i,1,L.v)

{

if(L.inG[i]==0)continue;

if(L.vec[i]==a){id_a=i;}

if(L.vec[i]==b){id_b=i;}

}//找到两个点的下标

L.edge++;//边数加1

L.map[id_a][id_b]=1;//标记两点有边

L.outdeep[id_a]++;

L.indeep[id_b]++;

}

intDeleteArc(G&L,chara,charb)

{//删除边

intid_a;

intid_b;

ff(i,1,L.v)

{

if(L.inG[i]==0)continue;

if(L.vec[i]==a){id_a=i;}

if(L.vec[i]==b){id_b=i;}

}//查出下标

L.edge--;

L.map[id_a][id_b]=0;//标记无边

L.outdeep[id_a]--;L.indeep[id_b]--;

}

(11)、功能选择函数

switch(op)

{

case0:

_0();break;case1:

_1();break;case2:

_2();break;

case3:

_3();break;case4:

_4();break;case5:

_5();break;

case6:

_6();break;case7:

_7();break;

case8:

_8();break;case9:

_9();break;

case10:

_10();break;case11:

_11();break;

case12:

_12();break;case13:

_13();break;

}

四、调试分析及测试

图4-1

图4-1是图的创建立。

遇到的问题:

1、边如何表示?

解决方案:

点用字母表示的同时有一个下标,表示边就找到两个点的下标,构边。

图4-2

图4-2表示的是图构成后的矩阵输出,遇到的问题:

1、如何输出一个删除过点的矩阵?

解决方案:

将图中的点标记,如果是1解决方案:

表示在图中,输出只输出在图中的就可以了。

2、如何更形像地表示出邻接矩阵而不只显示数字,另外要直观地看出哪两个结点的边。

解决方案:

在第一行和第一列输出相应的字符。

图4-3

图4-3表示的是图的深度优先遍历和广度优先遍历。

遇到问题:

1、光用图中的点的标记会重复遍历点?

解决方案:

另用一个sign数组标记是否此点被搜索过。

2、如何搜索非连通图?

解决方案:

搜索入口处对每个点遍历,搜过的和不在图中的不用。

图4-4

图4-4主要是添加边点,删除边点的操作。

遇到的问题:

1、如何表示一个点或边不在图中?

解决方案:

用图中的一个inG数组标记图中的点;map[i][j]表示边,有边等于1,无边等于0。

图4-5

图4-5表示的是相应的操作后的图的邻接矩阵表示。

图4-6

从图4-6可以看出经过点和边操作后的搜索结果,由些图可以看出e和c点都是孤立点。

图4-6

图4-7

图4-6和图4-7是对图的点的值和位置的操作

五、个人工作及创新

1、如何表示添加点和删除点。

解决方案:

(1)、用一个L.inG[]标记这个点在图中,每加一个点,点数加1,删除点的时候,只要将L.inG标记为0,无论是在搜索还是在遍历的时候,只要遇到不在图的点,就continue.

(2)、删除点时,将这个点标记不在图中,并将与之相连的边用一个for遍历所有在图中的点,只要和它有边的,把这些边全删除了。

2、添加边如何表示

解决方案:

先查出两个字符的下标,然后map[][]标记为1,同时入度和出度作出相应改变,还有就是边数加1。

3、遍历时重复遍历

借助一个数组sign表示此点是否被遍历,无则遍历之,否则continue。

六、小结

个人觉得数据结构最重要的是结构和算法两个方面,结构方面是一定要掌握好的。

无论是在抽象思维方面还是将来的工作上,都有很大的作用,然而算法方面,如何不从事相关的工作,或者不参加考研是没有多大必要去学的。

要真正理解一个算法是很花时间的

理解一个算法,不只是要看得懂,还要能够敲的出来,这个是要好深的内功的。

单从这个实验上来看,用到的算法并不是很多,只有一个深度和广度算得上是算法,其它的都是瞎热闹的。

其他的都是很笼统的遍历。

遇到的麻烦也不是很多,总是学数据结构没有编码就是瞎凑合,肯定是学不好的。

七、参考文献

[1].黄晓霞,萧蕴诗.数据挖掘应用研究及展望[J].计算机辅助工程.2001.4:

23-29

[2].黄解军,潘和平,万幼川.数据挖掘技术的应用研究.计算机工程与应用,2003,02:

45~48.

附录

以下是控制选择部分代码:

#include

usingnamespacestd;

#include

#include

#include

#defineff(i,a,b)for(inti=a;i<=b;i++)

#defineclear_(x,y)memset(x,y,sizeof(x))

#definema20

charaa,bb;

constintnum[]={1,3,4,5,4,2,4,34,56,7,2,1,1,3,4,9,6};

#include

voidmanu()//0

{

cout<<"\t\t\t\t有向图madebyCD_pLayer@copyright"<

cout<<"\t\t0菜单";

cout<<"\t\t\t6深度优先遍历"<

cout<<"\t\t1创建图";

cout<<"\t\t7广度优先遍历"<

cout<<"\t\t2销毁图";

cout<<"\t\t8查找结点的位置和值(不存在返回0)"<

cout<<"\t\t3添加结点(char)";

cout<<"\t9对图中的结点赋值(char)"<

cout<<"\t\t4删除结点(char)";

cout<<"\t10查找某结点的第一个邻接点(char)"<

cout<<"\t\t5添加边(char,char)";

cout<<"\t11删除边(char,char)"<

cout<

cout<<"\t\t\t12查找某结点的相对它第一个

邻接点的下一个邻接点(char)"<

cout<<"\t\t\t13以邻接矩阵输出图"<

cout<<"\t\t\t14退出系统"<

}

void_0(){manu();cout<<"操作结束"<

void_1(){CreatGraph(image);

cout<<"操作结束"<

void_2(){DestroyGraph(image);}

void_3(){chara;

cout<<"请输入要添加的结点:

"<>a;InserVex(image,a);

cout<<"操作结束"<

}

void_4(){

charaa;cout<<"请输入要删除的结点:

"<

cin>>aa;

DeleteVex(image,aa);

cout<<"操作结束"<

}

void_5(){

chara,b;cout<<"请输入要添加的边"<

cin>>a>>b;InsertArc(image,a,b);

cout<<"操作结束"<

}

void_6(){

cout<<"遍历序列是:

"<

clear_(sign,0);

ff(i,1,image.v)

{

if(image.inG[i]&&sign[i]==0)

{

DFSTraverse(i,image);

cout<

}

}

cout<<"操作结束"<

}

void_7(){

cout<<"遍历序列是:

"<

clear_(

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

当前位置:首页 > 解决方案 > 学习计划

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

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