收藏 分享(赏)

图的遍历操作实验报告.doc

上传人:精品资料 文档编号:10383616 上传时间:2019-11-05 格式:DOC 页数:13 大小:118.82KB
下载 相关 举报
图的遍历操作实验报告.doc_第1页
第1页 / 共13页
图的遍历操作实验报告.doc_第2页
第2页 / 共13页
图的遍历操作实验报告.doc_第3页
第3页 / 共13页
图的遍历操作实验报告.doc_第4页
第4页 / 共13页
图的遍历操作实验报告.doc_第5页
第5页 / 共13页
点击查看更多>>
资源描述

1、实验三、图的遍历操作一、 目的掌握有向图和无向图的概念;掌握邻接矩阵和邻接链表建立图的存储结构;掌握 DFS 及 BFS 对图的遍历操作;了解图结构在人工智能、工程等领域的广泛应用。二、 要求采用邻接矩阵和邻接链表作为图的存储结构,完成有向图和无向图的 DFS和 BFS 操作。三、 DFS 和 BFS 的基本思想深度优先搜索法 DFS 的基本思想:从图 G 中某个顶点 Vo 出发,首先访问Vo,然后选择一个与 Vo 相邻且没被访问过的顶点 Vi 访问,再从 Vi 出发选择一个与 Vi 相邻且没被访问过的顶点 Vj 访问,依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则回退到已被访问

2、的顶点序列中最后一个拥有未被访问的相邻顶点的顶点 W,从 W 出发按同样方法向前遍历。直到图中所有的顶点都被访问。广度优先算法 BFS 的基本思想:从图 G 中某个顶点 Vo 出发,首先访问Vo,然后访问与 Vo 相邻的所有未被访问过的顶点 V1,V2,Vt;再依次访问与 V1,V2,Vt 相邻的起且未被访问过的的所有顶点。如此继续,直到访问完图中的所有顶点。四、 示例程序1 邻接矩阵作为存储结构的程序示例#include“stdio.h“#include“stdlib.h“#define MaxVertexNum 100 /定义最大顶点数typedef structchar vexsMaxV

3、ertexNum; /顶点表int edgesMaxVertexNumMaxVertexNum; /邻接矩阵,可看作边表int n,e; /图中的顶点数 n 和边数 eMGraph; /用邻接矩阵表示的图的类型/=建立邻接矩阵=void CreatMGraph(MGraph *G)int i,j,k;char a;printf(“Input VertexNum(n) and EdgesNum(e): “);scanf(“%d,%d“, /输入顶点数和边数scanf(“%c“, printf(“Input Vertex string:“);for(i=0;in;i+) scanf(“%c“,G-

4、vexsi=a; /读入顶点信息,建立顶点表1for(i=0;in;i+)for(j=0;jn;j+)G-edgesij=0; /初始化邻接矩阵printf(“Input edges,Creat Adjacency Matrixn“);for(k=0;ke;k+) /读入 e 条边,建立邻接矩阵 scanf(“%d%d“, /输入边(Vi,Vj)的顶点序号G-edgesij=1; G-edgesji=1; /若为无向图,矩阵为对称矩阵;若建立有向图,去掉该条语句 /=定义标志向量,为全局变量=typedef enumFALSE,TRUE Boolean;Boolean visitedMaxVe

5、rtexNum;/=DFS:深度优先遍历的递归算法=void DFSM(MGraph *G,int i) /以 Vi 为出发点对邻接矩阵表示的图 G 进行 DFS 搜索,邻接矩阵是 0,1 矩阵int j;printf(“%c“,G-vexsi); /访问顶点 Vivisitedi=TRUE; /置已访问标志for(j=0;jn;j+) /依次搜索 Vi 的邻接点if(G-edgesij=1 /(Vi,Vj)E,且 Vj 未访问过,故 Vj为新出发点void DFS(MGraph *G) int i;for(i=0;in;i+)visitedi=FALSE; /标志向量初始化for(i=0;i

6、n;i+)if(!visitedi) /Vi 未访问过DFSM(G,i); /以 Vi 为源点开始 DFS 搜索/=BFS:广度优先遍历=void BFS(MGraph *G,int k) /以 Vk 为源点对用邻接矩阵表示的图 G 进行广度优先搜索int i,j,f=0,r=0;int cqMaxVertexNum; /定义队列 for(i=0;in;i+)visitedi=FALSE; /标志向量初始化for(i=0;in;i+)cqi=-1; /队列初始化2printf(“%c“,G-vexsk); /访问源点 Vkvisitedk=TRUE;cqr=k; /Vk 已访问,将其入队。注意

7、,实际上是将其序号入队while(cqf!=-1) /队非空则执行i=cqf; f=f+1; /Vf 出队for(j=0;jn;j+) /依次 Vi 的邻接点 Vjif(G-edgesij=1 /访问 Vjvisitedj=TRUE;r=r+1; cqr=j; /访问过 Vj 入队/=main=void main()int i;MGraph *G;G=(MGraph *)malloc(sizeof(MGraph); /为图 G 申请内存空间CreatMGraph(G); /建立邻接矩阵printf(“Print Graph DFS: “);DFS(G); /深度优先遍历printf(“n“);

8、printf(“Print Graph BFS: “);BFS(G,3); /以序号为 3 的顶点开始广度优先遍历printf(“n“);执行顺序:Input VertexNum(n) and EdgesNum(e): 8,9Input Vertex string: 01234567Input edges,Creat Adjacency Matrix0 10 21 31 42 52 63 74 75 6Print Graph DFS:01374256Print Graph BFS:31704256V6V4 V5V7V2V3V1V0Vo图 G 的示例32 邻接链表作为存储结构程序示例#inclu

9、de“stdio.h“#include“stdlib.h“#define MaxVertexNum 50 /定义最大顶点数typedef struct node /边表结点int adjvex; /邻接点域struct node *next; /链域EdgeNode;typedef struct vnode /顶点表结点char vertex; /顶点域EdgeNode *firstedge; /边表头指针VertexNode;typedef VertexNode AdjListMaxVertexNum; /AdjList 是邻接表类型typedef struct AdjList adjlis

10、t; /邻接表int n,e; /图中当前顶点数和边数 ALGraph; /图类型/=建立图的邻接表=void CreatALGraph(ALGraph *G)int i,j,k;char a;EdgeNode *s; /定义边表结点printf(“Input VertexNum(n) and EdgesNum(e): “);scanf(“%d,%d“, /读入顶点数和边数scanf(“%c“,printf(“Input Vertex string:“);for(i=0;in;i+) /建立边表scanf(“%c“,G-adjlisti.vertex=a; /读入顶点信息G-adjlisti.

11、firstedge=NULL; /边表置为空表printf(“Input edges,Creat Adjacency Listn“);for(k=0;ke;k+) /建立边表 scanf(“%d%d“, /读入边(Vi,Vj)的顶点对序号s=(EdgeNode *)malloc(sizeof(EdgeNode); /生成边表结点s-adjvex=j; /邻接点序号为 js-next=G-adjlisti.firstedge;G-adjlisti.firstedge=s; /将新结点*S 插入顶点 Vi 的边表头部s=(EdgeNode *)malloc(sizeof(EdgeNode); s-

12、adjvex=i; /邻接点序号为 is-next=G-adjlistj.firstedge; 4G-adjlistj.firstedge=s; /将新结点*S 插入顶点 Vj 的边表头部/=定义标志向量,为全局变量=typedef enumFALSE,TRUE Boolean;Boolean visitedMaxVertexNum;/=DFS:深度优先遍历的递归算法=void DFSM(ALGraph *G,int i) /以 Vi 为出发点对邻接链表表示的图 G 进行 DFS搜索EdgeNode *p;printf(“%c“,G-adjlisti.vertex); /访问顶点 Vivisi

13、tedi=TRUE; /标记 Vi 已访问p=G-adjlisti.firstedge; /取 Vi 边表的头指针while(p) /依次搜索 Vi 的邻接点 Vj,这里 j=p-adjvexif(! visitedp-adjvex) /若 Vj 尚未被访问DFSM(G,p-adjvex); /则以 Vj 为出发点向纵深搜索p=p-next; /找 Vi 的下一个邻接点void DFS(ALGraph *G)int i;for(i=0;in;i+)visitedi=FALSE; /标志向量初始化for(i=0;in;i+)if(!visitedi) /Vi 未访问过DFSM(G,i); /以

14、Vi 为源点开始 DFS 搜索/=BFS:广度优先遍历=void BFS(ALGraph *G,int k) /以 Vk 为源点对用邻接链表表示的图 G 进行广度优先搜索int i,f=0,r=0;EdgeNode *p;int cqMaxVertexNum; /定义 FIFO 队列for(i=0;in;i+)visitedi=FALSE; /标志向量初始化for(i=0;in;i+)cqi=-1; /初始化标志向量printf(“%c“,G-adjlistk.vertex); /访问源点 Vkvisitedk=TRUE;cqr=k; /Vk 已访问,将其入队。注意,实际上是将其序号5入队 w

15、hile(cqf!=-1) 队列非空则执行i=cqf; f=f+1; /Vi 出队p=G-adjlisti.firstedge; /取 Vi 的边表头指针while(p) /依次搜索 Vi 的邻接点 Vj(令 p-adjvex=j)if(!visitedp-adjvex) /若 Vj 未访问过printf(“%c“,G-adjlistp-adjvex.vertex); /访问 Vjvisitedp-adjvex=TRUE;r=r+1; cqr=p-adjvex; /访问过的 Vj 入队p=p-next; /找 Vi 的下一个邻接点/endwhile/=主函数=void main()int i;

16、ALGraph *G;G=(ALGraph *)malloc(sizeof(ALGraph);CreatALGraph(G);printf(“Print Graph DFS: “);DFS(G);printf(“n“);printf(“Print Graph BFS: “);BFS(G,3);printf(“n“);执行顺序:Input VertexNum(n) and EdgesNum(e): 8,9Input Vertex string: 01234567Input edges,Creat Adjacency List0 10 21 31 42 52 63 74 75 6Print Gra

17、ph DFS:02651473V6V4 V5V7V2V3V1V0Vo图 G 的示例6Print Graph BFS:37140265五、 修改后的代码1 邻接矩阵作为存储结构的程序#include“stdio.h“#include“stdlib.h“#define MaxVertexNum 100 /定义最大顶点数typedef structchar vexsMaxVertexNum; /顶点表int edgesMaxVertexNumMaxVertexNum; /邻接矩阵,可看作边表int n,e; /图中的顶点数 n 和边数 eMGraph; /用邻接矩阵表示的图的类型/=建立邻接矩阵=v

18、oid CreatMGraph(MGraph *G)int i,j,k;char a;printf(“Input VertexNum(n) and EdgesNum(e): “);scanf(“%d,%d“, /输入顶点数和边数scanf(“%c“, printf(“Input Vertex string:“);for(i=0;in;i+) scanf(“%c“,G-vexsi=a; /读入顶点信息,建立顶点表for(i=0;in;i+)for(j=0;jn;j+)G-edgesij=0; /初始化邻接矩阵printf(“Input edges,Creat Adjacency Matrixn“

19、);for(k=0;ke;k+) /读入 e 条边,建立邻接矩阵 scanf(“%d%d“, /输入边(Vi,Vj)的顶点序号G-edgesij=1; G-edgesji=1; /若为无向图,矩阵为对称矩阵;若建立有向图,去掉该条语句 /=定义标志向量,为全局变量=typedef enumFALSE,TRUE Boolean;Boolean visitedMaxVertexNum;/=DFS:深度优先遍历的递归算法=void DFSM(MGraph *G,int i) /以 Vi 为出发点对邻接矩阵表示的图 G 进行 DFS 搜索,邻接矩阵是 0,1 矩7阵int j;printf(“%c“,

20、G-vexsi); /访问顶点 Vivisitedi=TRUE; /置已访问标志for(j=0;jn;j+) /依次搜索 Vi 的邻接点if(G-edgesij=1 /(Vi,Vj)E,且 Vj 未访问过,故 Vj为新出发点void DFS(MGraph *G) int i;for(i=0;in;i+)visitedi=FALSE; /标志向量初始化for(i=0;in;i+)if(!visitedi) /Vi 未访问过DFSM(G,i); /以 Vi 为源点开始 DFS 搜索/=BFS:广度优先遍历=void BFS(MGraph *G,int k) /以 Vk 为源点对用邻接矩阵表示的图

21、G 进行广度优先搜索int i,j,f=0,r=0;int cqMaxVertexNum; /定义队列 for(i=0;in;i+)visitedi=FALSE; /标志向量初始化for(i=0;in;i+)cqi=-1; /队列初始化printf(“%c“,G-vexsk); /访问源点 Vkvisitedk=TRUE;cqr=k; /Vk 已访问,将其入队。注意,实际上是将其序号入队while(cqf!=-1) /队非空则执行i=cqf; f=f+1; /Vf 出队for(j=0;jn;j+) /依次 Vi 的邻接点 Vjif(G-edgesij=1 /访问 Vjvisitedj=TRUE

22、; r=r+1; cqr=j; /访问过 Vj 入队/=main=void main()8MGraph *G;G=(MGraph *)malloc(sizeof(MGraph); /为图 G 申请内存空间CreatMGraph(G); /建立邻接矩阵printf(“Print Graph DFS: “);DFS(G); /深度优先遍历printf(“n“);printf(“Print Graph BFS: “);BFS(G,3); /以序号为 3 的顶点开始广度优先遍历printf(“n“);2 邻接链表作为存储结构程序#include“stdio.h“#include“stdlib.h“#d

23、efine MaxVertexNum 50 /定义最大顶点数typedef struct node /边表结点int adjvex; /邻接点域struct node *next; /链域EdgeNode;typedef struct vnode /顶点表结点char vertex; /顶点域EdgeNode *firstedge; /边表头指针VertexNode;typedef VertexNode AdjListMaxVertexNum; /AdjList 是邻接表类型typedef struct AdjList adjlist; /邻接表int n,e; /图中当前顶点数和边数 ALG

24、raph; /图类型/=建立图的邻接表=void CreatALGraph(ALGraph *G)int i,j,k;char a;EdgeNode *s; /定义边表结点printf(“Input VertexNum(n) and EdgesNum(e): “);scanf(“%d,%d“, /读入顶点数和边数scanf(“%c“,printf(“Input Vertex string:“);for(i=0;in;i+) /建立边表scanf(“%c“,G-adjlisti.vertex=a; /读入顶点信息G-adjlisti.firstedge=NULL; /边表置为空表9printf(

25、“Input edges,Creat Adjacency Listn“);for(k=0;ke;k+) /建立边表 scanf(“%d%d“, /读入边(Vi,Vj)的顶点对序号s=(EdgeNode *)malloc(sizeof(EdgeNode); /生成边表结点s-adjvex=j; /邻接点序号为 js-next=G-adjlisti.firstedge;G-adjlisti.firstedge=s; /将新结点*S 插入顶点 Vi 的边表头部s=(EdgeNode *)malloc(sizeof(EdgeNode); s-adjvex=i; /邻接点序号为 is-next=G-ad

26、jlistj.firstedge; G-adjlistj.firstedge=s; /将新结点*S 插入顶点 Vj 的边表头部/=定义标志向量,为全局变量=typedef enumFALSE,TRUE Boolean;Boolean visitedMaxVertexNum;/=DFS:深度优先遍历的递归算法=void DFSM(ALGraph *G,int i) /以 Vi 为出发点对邻接链表表示的图 G 进行 DFS搜索EdgeNode *p;printf(“%c“,G-adjlisti.vertex); /访问顶点 Vivisitedi=TRUE; /标记 Vi 已访问p=G-adjlis

27、ti.firstedge; /取 Vi 边表的头指针while(p) /依次搜索 Vi 的邻接点 Vj,这里 j=p-adjvexif(! visitedp-adjvex) /若 Vj 尚未被访问DFSM(G,p-adjvex); /则以 Vj 为出发点向纵深搜索p=p-next; /找 Vi 的下一个邻接点void DFS(ALGraph *G)int i;for(i=0;in;i+)visitedi=FALSE; /标志向量初始化for(i=0;in;i+)if(!visitedi) /Vi 未访问过 DFSM(G,i); /以Vi 为源点开始 DFS 搜索DFSM(G,i);/=BFS:

28、广度优先遍历=void BFS(ALGraph *G,int k) /以 Vk 为源点对10用邻接链表表示的图 G 进行广度优先搜索int i,f=0,r=0; EdgeNode *p; int cqMaxVertexNum; /定义 FIFO 队列 for(i=0;in;i+)visitedi=FALSE; /标志向量初始化for(i=0;in;i+)cqi=-1; /初始化标志向量printf(“%c“,G-adjlistk.vertex); /访问源点 Vkvisitedk=TRUE;cqr=k; /Vk 已访问,将其入队。注意,实际上是将其序号入队 while(cqf!=-1) /队列

29、非空则执行i=cqf; f=f+1; /Vi 出队p=G-adjlisti.firstedge; /取 Vi 的边表头指针while(p) /依次搜索 Vi 的邻接点 Vj(令 p-adjvex=j)if(!visitedp-adjvex) /若 Vj 未访问过printf(“%c“,G-adjlistp-adjvex.vertex); /访问 Vjvisitedp-adjvex=TRUE;r=r+1; cqr=p-adjvex; /访问过的 Vj 入队p=p-next; /找 Vi 的下一个邻接点/endwhile/=主函数=void main()ALGraph *G;G=(ALGraph

30、*)malloc(sizeof(ALGraph);CreatALGraph(G);printf(“Print Graph DFS: “);DFS(G);printf(“n“);printf(“Print Graph BFS: “);BFS(G,3);printf(“n“);六、 实验内容1 调试程序。设计一个有向图和一个无向图,任选一种存储结构,完成有向图和无向图的 DFS(深度优先遍历)和 BFS(广度优先遍历)的操作。邻接矩阵作为存储结构的运行结果:11邻接链表作为存储结构的运行结果:六、实验报告要求画出你所设计的图,写出两种方法的遍历序列。邻接矩阵:V0 V1 V2 V3 V4 V5 V6 V7V6V4 V5V7V2V3V1V0Vo图 G 的示例12V0 0 1 1 0 0 0 0 0V1 1 0 0 1 1 0 0 0V2 1 0 0 0 0 1 1 0V3 0 1 0 0 0 0 0 1V4 1 0 0 0 0 0 0 1V5 0 1 0 0 0 0 1 0V6 0 1 0 0 0 1 0 0V7 0 0 0 1 1 0 0V0 0 2 1 V1 1 4 3 0 V2 2 6 5 0 V3 3 4 1 V4 4 7 1 V5 5 6 2 V6 6 5 2 V7 7 4 3 深度遍历为:02651473广度遍历为:37140265

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

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报