图的实验报告.docx

上传人:b****7 文档编号:9457706 上传时间:2023-02-04 格式:DOCX 页数:23 大小:19.11KB
下载 相关 举报
图的实验报告.docx_第1页
第1页 / 共23页
图的实验报告.docx_第2页
第2页 / 共23页
图的实验报告.docx_第3页
第3页 / 共23页
图的实验报告.docx_第4页
第4页 / 共23页
图的实验报告.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

图的实验报告.docx

《图的实验报告.docx》由会员分享,可在线阅读,更多相关《图的实验报告.docx(23页珍藏版)》请在冰豆网上搜索。

图的实验报告.docx

图的实验报告

 

《数据结构》

 

实验报告

 

题目:

 

一、实现图的邻接矩阵和邻接表存储

 

(一)需求分析

对于下图所示的有向图G,编写一个程序完成如下功能:

 

1.建立G的邻接矩阵并输出之

2.由G的邻接矩阵产生邻接表并输出之

3.再由2的邻接表产生对应的邻接矩阵并输出之

 

(二)系统设计

1、本程序中用到的所有抽象数据类型的定义;

typedefstruct

{intno;InfoTypeinfo;

}VertexType;

typedefstruct

//顶点类型

//图的定义

{intedges[MAXV][MAXV];

intvexnum,arcnum;

VertexTypevexs[MAXV];

}MGraph;

//图的邻接矩阵类型

typedefstructANode

//弧的结点结构类型

{intadjvex;

structANode*nextarc;

InfoTypeinfo;

}ArcNode;

typedefintVertex;

typedefstructVnode

//邻接表头结点的类型

{Vertexdata;

ArcNode*firstarc;

//指向第一条弧

}VNode;

typedefVNodeAdjList[MAXV];

//AdjList

是邻接表类型

typedefstruct

 

{

 

AdjListadjlist;

 

//邻接表

 

intn,e;

}ALGraph;

//图的邻接表类型

2、主程序的流程以及各程序模块之间的层次调用关系,函数的调用关系图:

 

Main()

 

DispMat(g);输出邻

MatToList(g,G);将邻接矩

DispAdj(G);输出

接矩阵g

阵g转换成邻接表G

邻接表G

 

3、列出各个功能模块的主要功能及输入输出参数

voidMatToList(MGraphg,ALGraph*&G)将邻接矩阵

voidDispMat(MGraphg)输出邻接矩阵g

voidDispAdj(ALGraph*G)输出邻接表G

intOutDegree(ALGraph*G,intv)求图中每个顶点的出度

g转换成邻接表

G

(三)调试分析

 

调试过程中还是出现了一些拼写错误,

 

经检查后都能及时修正。

 

有些是语法设计上的小

错误,比如一些参变量的初始值设置错误,

使得程序调试出错。

在小组讨论分析后纠正了这

些结果,并尽量改进了算法的性能,减小时间复杂度。

将邻接矩阵

g转换成邻接表

G,输出邻接矩阵

g,输出邻接表

G的算法时间复杂度都是

O(n^2)。

通过这次实验,对图的存储方法有了更深刻的印象。

(四)测试结果

 

测试结果:

(1)有向图G的邻接矩阵为

 

0104

 

0092

3580

 

0060

(2)图G的邻接矩阵转换成的邻接表为:

 

0:

13

1:

23

 

2:

012

 

3:

2

(五)用户手册

 

不需要输入参数

 

(六)附录

源程序

#include

#include

#defineMAXV100

#defineINF32767

//最大顶点个数

//INF表示∞

typedefintInfoType;

typedefstruct

{

intno;

//顶点编号

InfoTypeinfo;

}VertexType;

typedefstruct

//顶点其他信息

//顶点类型

//图的定义

{

intedges[MAXV][MAXV];

//邻接矩阵

intvexnum,arcnum;VertexTypevexs[MAXV];

//顶点数,弧数

//存放顶点信息

}MGraph;

//图的邻接矩阵类型

typedefstructANode

//弧的结点结构类型

{

intadjvex;

structANode*nextarc;

InfoTypeinfo;

//该弧的终点位置

//指向下一条弧的指针

//该弧的相关信息,这里用于存放权值

}ArcNode;

typedefintVertex;

typedefstructVnode

//邻接表头结点的类型

{

Vertexdata;

ArcNode*firstarc;

//顶点信息

//指向第一条弧

}VNode;

typedefVNodeAdjList[MAXV];

//AdjList

是邻接表类型

typedefstruct

{

AdjListadjlist;//邻接表

intn,e;//图中顶点数n和边数

}ALGraph;//图的邻接表类型

voidMatToList(MGraphg,ALGraph*&G)//将邻接矩阵

{

 

e

 

g转换成邻接表

 

G

inti,j,n=g.vexnum;

//n

为顶点数

ArcNode*p;

G=(ALGraph*)malloc(sizeof(ALGraph));

for(i=0;i

//给邻接表中所有头结点的指针域置初值

 

G->adjlist[i].firstarc=NULL;

for(i=0;i

//检查邻接矩阵中每个元素

for(j=n-1;j>=0;j--)

if(g.edges[i][j]!

=0)

//邻接矩阵的当前元素不为

0

{

p=(ArcNode*)malloc(sizeof(ArcNode));

//创建一个结点

*p

p->adjvex=j;

p->info=g.edges[i][j];

p->nextarc=G->adjlist[i].firstarc;

//将*p

链到链表后

G->adjlist[i].firstarc=p;

}

G->n=n;G->e=g.arcnum;

}

voidDispMat(MGraphg)

//输出邻接矩阵g

{

inti,j;

for(i=0;i

{

for(j=0;j

if(g.edges[i][j]==INF)

printf("%3s","∞");

else

printf("%3d",g.edges[i][j]);

printf("\n");

}

}

voidDispAdj(ALGraph*G)

//输出邻接表G

{

inti;

ArcNode*p;

for(i=0;in;i++)

{

p=G->adjlist[i].firstarc;

if(p!

=NULL)printf("%3d:

",i);

while(p!

=NULL)

{

printf("%3d",p->adjvex);

p=p->nextarc;

}

printf("\n");

}

}

 

intOutDegree(ALGraph*G,intv)//求图中每个顶点的出度

{

ArcNode*p;

intn=0;

p=G->adjlist[v].firstarc;

while(p!

=NULL)

{n++;

p=p->nextarc;

}

returnn;

}

voidmain()

{

inti,j;

MGraphg,g1;

ALGraph*G;

intA[MAXV][4]={

{0,1,0,4},

{0,0,9,2},

{3,5,8,0},

{0,0,6,0},};

g.vexnum=4;g.arcnum=8;

for(i=0;i

for(j=0;j

g.edges[i][j]=A[i][j];

printf("\n");

printf("

(1)有向图G的邻接矩阵为:

\n");

DispMat(g);

G=(ALGraph*)malloc(sizeof(ALGraph));

printf("

(2)图G的邻接矩阵转换成邻接表为:

\n");

MatToList(g,G);

DispAdj(G);

}

运行后结果显示:

 

二、实现图的遍历算法

 

(一)需求分析

 

对于上图G,编写一个程序输出从顶点0开始的深度优先遍历序列(递归算法)和广度优先遍历序列(非递归算法)。

 

(二)系统设计

1.说明本程序中用到的所有抽象数据类型的定义;

typedefstruct{

charvexs[MaxVertexNum];//顶点表

intedges[MaxVertexNum][MaxVertexNum];//邻接矩阵,可看作边表

intn,e;//图中的顶点数n和边数e

}MGraph;//用邻接矩阵表示的图的类型

2.主程序的流程以及各程序模块之间的层次调用关系,画出函数的调用关系图。

 

Main()

 

CreatMGraph(G)

DFS(G);深度

BFS(G,0);以序号

为3的顶点开始广

建立邻接矩阵

优先遍历

度优先遍历

 

3.列出各个功能模块的主要功能及输入输出参数。

 

voidCreatMGraph(MGraph*G)

 

创建邻接矩阵

G

voidDFSM(MGraph*G,inti)以Vi为出发点对0-1邻接矩阵表示的图G进行DFS搜索

voidDFS(MGraph*G)深度优先遍历

voidBFS(MGraph*G,intk)以Vk为源点对用邻接矩阵表示的图G进行广度优先遍历

(三)调试分析

 

调试过程中还是出现了一些拼写错误,

经检查后都能及时修正。

有些是语法设计上的小

错误,比如一些参变量的初始值设置错误,

使得程序调试出错。

在小组讨论分析后纠正了这

些结果,并尽量改进了算法的性能,减小时间复杂度。

创建邻接矩阵算法的时间复杂度是O(2n+n^2),深度优先遍历和广度优先遍历的算法时

间复杂度都是O(n^2)。

通过这次实验,加深了对遍历图的递归和非递归的算法的印象。

(四)测试结果

输入节点数

8和边数

9,各节点标示

01234567,边是

01,02,13,14,25,26,37,47,56

运行后深度优先遍历是01374256,广度优先遍历是01234567。

 

(五)用户手册

 

根据提示输入节点和边数,然后再由提示输入各节点标示,接下来输入各边。

运行后便得

到深度优先遍历和广度优先遍历结果。

 

(六)附录

源程序:

#include"stdio.h"

#include"stdlib.h"

#defineMaxVertexNum100//定义最大顶点数

typedefstruct{

charvexs[MaxVertexNum];//顶点表

intedges[MaxVertexNum][MaxVertexNum];//邻接矩阵,可看作边表

intn,e;//图中的顶点数n和边数e

}MGraph;//用邻接矩阵表示的图的类型

voidCreatMGraph(MGraph*G)//建立邻接矩阵

{

inti,j,k;

chara;

printf("InputVertexNum(n)andEdgesNum(e):

");

scanf("%d,%d",&G->n,&G->e);//输入顶点数和边数scanf("%c",&a);

printf("InputVertexstring:

");

for(i=0;in;i++)

{

 

scanf("%c",&a);

G->vexs[i]=a;//读入顶点信息,建立顶点表

}

for(i=0;in;i++)

for(j=0;jn;j++)

G->edges[i][j]=0;//初始化邻接矩阵

printf("Inputedges,CreatAdjacencyMatrix\n");

for(k=0;ke;k++){//读入e条边,建立邻接矩阵

scanf("%d%d",&i,&j);//输入边(Vi,Vj)的顶点序号

G->edges[i][j]=1;

G->edges[j][i]=1;//若为无向图,矩阵为对称矩阵;若建立有向图,去掉该条语句

}

}

typedefenum{FALSE,TRUE}Boolean;

Booleanvisited[MaxVertexNum];

voidDFSM(MGraph*G,inti)

{//

Vi

为出发点对邻接矩阵表示的图

G进行

DFS

搜索,邻接矩阵是

0,1矩阵

intj;

printf("%c",G->vexs[i]);//访问顶点Vi

visited[i]=TRUE;//置已访问标志

for(j=0;jn;j++)//依次搜索Vi的邻接点

if(G->edges[i][j]==1&&!

visited[j])

DFSM(G,j);//(Vi,Vj)∈E,且

 

Vj

 

未访问过,故

 

Vj

 

为新出发点

}

voidDFS(MGraph*G)

{

inti;

for(i=0;in;i++)

visited[i]=FALSE;

//标志向量初始化

for(i=0;in;i++)

if(!

visited[i])

DFSM(G,i);

//Vi

未访问过

//以Vi为源点开始

 

DFS

 

搜索

}

voidBFS(MGraph*G,intk)

{//以Vk

 

为源点对用邻接矩阵表示的图

 

G进行广度优先搜索

inti,j,f=0,r=0;

intcq[MaxVertexNum];

for(i=0;in;i++)

visited[i]=FALSE;

for(i=0;in;i++)

cq[i]=-1;

printf("%c",G->vexs[k]);

visited[k]=TRUE;

cq[r]=k;//Vk

 

//定义队列

 

//标志向量初始化

 

//队列初始化

//访问源点Vk

 

已访问,将其入队。

注意,实际上是将其序号入队

 

while(cq[f]!

=-1){//队非空则执行

i=cq[f];f=f+1;//Vf出队

for(j=0;jn;j++)//依次Vi

if(G->edges[i][j]==1&&!

visited[j]){

printf("%c",G->vexs[j]);

visited[j]=TRUE;

r=r+1;cq[r]=j;//访问过

 

的邻接点Vj

//Vj未访问

//访问Vj

 

Vj入队

}

}

}

voidmain()

{

inti;

MGraph*G;

G=(MGraph*)malloc(sizeof(MGraph));//为图G申请内存空间

CreatMGraph(G);//建立邻接矩阵

printf("PrintGraphDFS:

");

DFS(G);//深度优先遍历

printf("\n");

printf("PrintGraphBFS:

");

BFS(G,0);//以序号为3的顶点开始广度优先遍历

printf("\n");

}

测试结果

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

当前位置:首页 > 教学研究 > 教学计划

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

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