数据结构实验报告无向图的邻接矩阵存储结构Word格式.docx
《数据结构实验报告无向图的邻接矩阵存储结构Word格式.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告无向图的邻接矩阵存储结构Word格式.docx(24页珍藏版)》请在冰豆网上搜索。
四、主要技术路线提示
用一维数组存放图的顶点信息,二维数组存放各边信息。
五、进度安排
按教学计划规定,数据结构课程设计为2周,其进度及时间大致分配如下:
序号
设计内容
天数
1
分析问题,给出数学模型,选择数据结构
2
设计算法,给出算法描述
3
给出源程序清单
4
编辑、编译、调试源程序
5
编写课程设计报告
总计
10
六、推荐参考资料
[1]严蔚敏,吴伟民.数据结构.清华大学出版社出版。
[2]严蔚敏,吴伟民.数据结构题集(C语言版).清华大学出版社.2003年5月。
[3]唐策善,李龙澎.数据结构(作C语言描述).高等教育出版社.2001年9月
[4]朱战立.数据结构(C++语言描述)(第二版本).高等出版社出版.2004年4月
[5]胡学钢.数据结构(C语言版).高等教育出版社.2004年8月
指导教师签名日期年月日
系主任审核日期年月日
目录
引言5
1需求分析6
1.1任务与分析6
1.2测试数据6
2概要设计7
2.1ADT描述7
2.2程序模块结构8
2.3 各功能模块10
3 详细设计11
3.1类的定义11
3.2初始化12
3.3图的构建操作12
3.4输出操作13
3.5get操作13
3.6插入操作14
3.7删除操作14
3.8求顶点的度操作15
3.10判断连通操作16
3.11主函数17
4调试分析20
4.1测试数据20
4.2调试问题20
4.3算法时间复杂度20
4.4经验和心得体会21
5 用户使用说明21
6测试结果21
6.1创建图21
6.2插入节点22
6.3深度优先遍历22
6.4求各顶点的度23
6.5输出图23
6.6判断是否连通24
6.7求边的权值24
6.8插入边25
6.9删除边25
结论27
致谢28
摘要
随着计算机的普及,涉及计算机相关的科目也越来越普遍,其中数据结构是计算机专业重要的专业基础课程与核心课程之一,为适应我国计算机科学技术的发展和应用,学好数据结构非常必要,然而要掌握数据结构的知识非常难,所以对“数据结构”的课程设计比不可少。
本说明书是对“无向图的邻接矩阵存储结构”课程设计的说明。
首先是对需求分析的简要阐述,说明系统要完成的任务和相应的分析,并给出测试数据。
其次是概要设计,说明所有抽象数据类型的定义、主程序的流程以及各程序模块之间的层次关系,以及ADT描述。
然后是详细设计,描述实现概要设计中定义的基本功操作和所有数据类型,以及函数的功能及代码实现。
再次是对系统的调试分析说明,以及遇到的问题和解决问题的方法。
然后是用户使用说明书的阐述,然后是测试的数据和结果的分析,最后是对本次课程设计的结论。
关键词:
网络化;
计算机;
对策;
图;
储存。
引言
数据结构是计算机存储、组织数据的方式。
数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。
数据结构往往同高效的检索算法和索引技术有关。
选择了数据结构,算法也随之确定,是数据而不是算法是系统构造的关键因素。
这种洞见导致了许多种软件设计方法和程序设计语言的出现,面向对象的程序设计语言就是其中之一。
此次课程设计根据课堂讲授内容,下发任务书,要求学生完成相应系统,以消化课堂所讲解的内容;
通过调试典型例题或习题积累调试C++程序从而获得数据结构的编程经验;
通过完成此项课程设计,逐渐培养学生的编程能力、用计算机解决实际问题的能力,并充分理解图的矩阵储存方法。
此次课程设计题目为《无向图的邻接矩阵存储结构》,所利用工具为Microsoftvisualstudio2008.
1需求分析
随着计算机的普及,信息的存储逐渐和我们的日常生活变得密切起来,而数据的存储方式也多种多样,比如树、链表、数组、图等等。
为了充分体现图的矩阵储存结构的优势与功能,要求本系统应达到以下要求:
1.图是无向带权图
2.能从键盘上输入各条边和边上的权值;
3.构造图的邻接矩阵和顶点集。
4.输出图的各顶点和邻接矩阵
5.插入一条边
6.删除一条边
7.求出各顶点的度
8.判断该图是否是连通图,若是,返回1;
9.使用深度遍历算法,输出遍历序列。
1.1任务与分析
邻接矩阵是表示图形中顶点之间相邻关系的矩阵。
设G=(V,E)是具有n个顶点的图,则G的邻接矩阵是n阶方阵。
为了实现此算法,用一维数组a[]存放图的顶点信息,二维数组b[][]存放各边信息。
顶点或者边存在,则该数组应有值,通过此来进行建立、插入、删除。
其余方法也将能通过数组的特性来实现。
1.2测试数据
1.建立图的矩阵存储结构,第一次建立连通图A1,第二次建立非连通图A2。
如下:
图1.1测试数据
2.选择输出图
3.选择插入节点,插入4
4.选择插入边,在3,4节点中插入边,权值为55
5.选择深度优先搜索
6.选择判断是否连通
7.选择求最小生成树
8.选择求各顶点的度
9.选择退出,重新运行,此次建立A2的图,再次进行测试。
2概要设计
2.1ADT描述
ADTGlist
{
{VR}={图的顶点和边}
VR={<
v,w>
|v,w∈V,<
表示顶点v和w间的边;
}
基本操作:
初始化空图;
输入建立图;
深度优先遍历图;
确定图中的顶点数目;
确定图中边的数目;
在图中插入一个顶点;
在图中插入一条边;
删除图中一个顶点
删除图中的一条边;
求顶点的度;
求最小生成树;
}ADTGraph;
2.2程序模块结构
图2.1:
模块结构
2.2.1 结构体定义
本系统未采用结构体方法,类的定义如下:
定义顶点:
nodecount,edgecount边:
已经分别存放顶点和边的两个数组:
a[MaxNode]和b[MaxNode][MaxNode];
其余成员函数均以public形式声明。
在邻接矩阵表示的图中,顶点信息用一维数组表示a[]。
在简单情况下可省略,仅以下标值代表顶点序号。
若需要,顶点信息更加丰富。
边(或弧)信息用二维数组表示b[][],这也是邻接矩阵。
包含边的权值。
在类中数据成员有4个,重要的是邻接矩阵Edge[][]、总边数edgecount和顶点数nodecount。
classGraph1
private:
intnodecount;
//节点
intedgecount;
//边
inta[MaxNode];
//顶点信息组
//set<
int>
a;
intb[MaxNode][MaxNode];
//权值信息组
public:
Graph1(int);
//构造函数
intgetNodeCount();
//当前的节点数
intgetEdgeCount();
//当前的边数
voidinsertNode(int);
//插入一个节点
voidisertEdge(int,int,int);
//插入一条边
voiddeleteEdge(int,int);
//删除一条边
boolisliantong();
//判断是否连通
intgetWeight(int,int);
//获得某条边的权值
intDepth(int);
//深度遍历准备,用于建立顶点访问数组和记录所访问顶点个数
voidDepth(intv,intvisited[],int&
n);
//深度遍历
voidoutDu(Graph1G);
//输出节点个数
voidPrintOut(Graph1G);
//输出图
voidCreatG(intn,inte);
//建立图
};
2.3 各功能模块
以下将以注释形式为每个函数的功能进行声明:
构造函数:
Graph1(int)用于初始化图
get函数:
intgetNodeCount();
得到当前的节点数
intgetWeight(int,int);
获得某条边的权值
intgetEdgeCount();
得到当前的边数
插入函数:
voidinsertNode(int);
插入一个节点
voidisertEdge(int,int,int);
插入一条边
删除函数:
voiddeleteEdge(int,int);
删除一条边
判断函数:
boolisliantong();
判断是否连通
遍历函数1:
intDepth(int);
遍历函数2:
voidDepth(intv,intvisited[],int&
求度函数:
voidoutDu(Graph1G);
输出节点个数
输出函数:
voidPrintOut(Graph1G);
输出图
构建函数:
voidCreatG(intn,inte);
建立图
3 详细设计
3.1类的定义
voidprim(int);
//生成最小树
3.2初始化
初始化邻接矩阵以及有关参数,通过for循环将数组的值都初始化为0,使之成为一个空图。
Graph1:
:
Graph1(ints=MaxNode)//构造函数
{
for(inti=0;
i<
=s-1;
i++)
for(intj=0;
j<
j++)
b[i][j]=0;
nodecount=0;
for(intk=0;
k<
k++)
a[k]=-1;
}
3.3图的构建操作
在主函数中要求输入需要构建的图的顶点数和边数,调用构建函数,分别用两个for语句来构建图(即输入顶点的值和边的权值),此处要求输入有一定的顺序,不能随意输入。
voidGraph1:
CreatG(intn,inte)
{inti,vi,vj,w;
edgecount=e;
nodecount=n;
cout<
<
endl<
"
输入顶点的信息(暂设为整型):
;
for(i=0;
i<
nodecount;
i++)
{cout<
\n"
i+1<
"
;
cin>
>
a[i];
edgecount;
i++)//输入两个顶点编号和边权值
输入边的信息(vi,vj,w):
endl;
vi>
vj>
w;
b[vi-1][vj-1]=w;
b[vj-1][vi-1]=w;
3.4输出操作
本函数通过传过来的对象G得到相关数组,通过for循环来分别输出顶点数组和边的权值数组(邻接矩阵)。
PrintOut(Graph1G)
{inti;
\n输出顶点的信息:
G.getNodeCount();
i++)cout<
G.a[i]<
\n输出邻接矩阵:
i++)
for(intj=0;
j<
G.getNodeCount();
j++)cout<
G.b[i][j]<
3.5get操作
用于得到图的顶点数、边数、权值
intGraph1:
getNodeCount()//当前的节点数
returnnodecount;
intGraph1:
getEdgeCount()//当前的边数
returnedgecount;
}
getWeight(intx,inty)//获得某条边的权值
returnb[x-1][y-1];
3.6插入操作
插入顶点:
通过将传来的值(顶点值)赋到一个当前顶点数下一个的数组元素中实现插入功能,此时顶点树加1。
插入边:
原理与插入顶点相同,通过传过来的两个顶点信息与权值进行相应赋值,不过此时应该注意表示同一条边的两个数组都该赋值。
voidGraph1:
insertNode(intit)//插入一个节点
a[nodecount++]=it;
当前节点数为:
nodecount<
isertEdge(intx,inty,intw)//插入一条边
b[x-1][y-1]=w;
b[y-1][x-1]=w;
该边插入成功!
edgecount++;
3.7删除操作
将相应的数组值赋为0从而达到删除目的。
deleteEdge(intx,inty)//删除一条边
b[x-1][y-1]=0;
b[y-1][x-1]=0;
边("
x<
"
y<
)已经成功删除!
edgecount--;
3.8求顶点的度操作
通过两个for循环来查找各顶点,判断其是否有边(权值),有边的话又有几条边,每找到一条边则度数加一,记录到存放顶点的度数的数组M[]中,搜索完成后输出各顶点的度。
outDu(Graph1G)//输出各点的度
intm[Max]={0},k,i;
for(k=0;
for(i=0;
if(G.b[k][i]!
=0)
m[k]++;
各点的度:
顶点"
的度:
m[i]<
3.9深度遍历操作
图的深度优先遍历DFS算法是沿着某初始顶点出发的一条路径,尽可能深入地前进,即每次在访问完当前顶点后,首先访问当前顶点的一个未被访问过的邻接顶点,然后去访问这个邻接点的一个未被访问过的邻接点,这是一个递归算法。
其中第一个遍历函数Depth(intnode)其主要作用是构建访问数组intv[],以及调用核心遍历函数Depth(intv,intvisited[],int&
n),其中的n是用来记录访问的顶点数目,用于判断图的连通性。
Depth(intnode)
intn=0;
intv[MaxNode];
=nodecount-1;
v[i]=0;
Depth(node,v,n);
returnn;
//n记录访问节点数,用于判断是否连通
Depth(intv,intvisited[],int&
n)
v+1<
//访问顶点v
visited[v]=1;
//标记顶点v已访问
n++;
//n记录访问节点数
for(intcol=0;
col<
col++)
{if(b[v][col]==0||b[v][col]==Max)
continue;
//找v一个邻接点col
if(!
visited[col])Depth(col,visited,n);
//调用深度递归遍历
3.10判断连通操作
通过调用遍历函数得到所能访问的顶点数n,然后判断n与当前顶点数是否相等来确认是否连通。
boolGraph1:
isliantong()//判断是否连通
n=Depth(0);
该图的总节点数为:
!
其中一个连通分量连通的节点数为:
n<
if(n==nodecount)//访问到的节点数与顶点数是否相等
return1;
elsereturn0;
3.11主函数
主函数的主要功能是引导构建新图的邻接矩阵存储结构,并且制作菜单、调用各个相应的功能函数。
intmain(){
Graph1G(10);
intx,y,w;
intnode;
cout<
你好,请问你向图添加几个节点?
几条边?
请依次从键盘输入!
intn;
cin>
n;
inte;
e;
G.CreatG(n,e);
恭喜你!
你的图已经建立成功!
//system("
pause"
);
while(true)
//system("
cls"
***********************"
*请选择你要进行的操作:
*"
*1--输出图!
*"
*2--判断图是否连通!
*3--表示深度优先搜索!
*4--表示求各顶点的度!
*5--表示插入新节点!
*6--表示删除边!
*7--求边的权值*"
*8--插入新的边!
*0--表示结束操作!
intchoice;
请你做出选择!
choice;
switch(choice)
case1:
G.PrintOut(G);
break;
case2:
if(G.isliantong())
该图是连通的!
elsecout<
该图不是连通的!
case3:
intnode;
请输入你选择的起始节点!
node;
深度优先搜索结果为:
G.Depth(node-1);
case4:
G.outDu(G);
case5:
请输入你要插入的新节点!
G.insertNode(node);
case6:
请输入你要删除的边!
x>
y;
G.deleteEdge(x,y);
case7:
请输入你要查询的边的两个顶点"
G.getWeight(x,y)<
case8:
请输入你要添加的"
e<
条边以及边上对应的权值!
y>
G.isertEdge(x,y,w);
case0:
感谢使用!
return0;
/