收藏 分享(赏)

图的深度广度遍历(算法与数据结构课程设计).doc

上传人:精品资料 文档编号:10414247 上传时间:2019-11-08 格式:DOC 页数:15 大小:526.50KB
下载 相关 举报
图的深度广度遍历(算法与数据结构课程设计).doc_第1页
第1页 / 共15页
图的深度广度遍历(算法与数据结构课程设计).doc_第2页
第2页 / 共15页
图的深度广度遍历(算法与数据结构课程设计).doc_第3页
第3页 / 共15页
图的深度广度遍历(算法与数据结构课程设计).doc_第4页
第4页 / 共15页
图的深度广度遍历(算法与数据结构课程设计).doc_第5页
第5页 / 共15页
点击查看更多>>
资源描述

1、wilyes11 收集 博客(与学习无关) :http:/ 顶点向量的存储。用两个数组分别存储数据(定点)的信息和数据元素之间的关系(边或弧)的信息。2、邻接表邻接表是图的一种链式存储结构。在邻接表中,对图中每个定点建立一个单链表,第i 个单链表中的节点表示依附于定点 vi 的边。每个节点由 3 个域组成,其中邻接点域(adjvex)指示与定点 vi 邻接的点在图中的位置,链域(nextarc)指示下一条边或弧的节点;数据域(info)存储和边或弧相关的信息,如权值等。每个链表上附设一个头节点。wilyes11 收集 博客(与学习无关) :http:/ 的名或其他有关信息的数据域(data)

2、。3、图的深度遍历深度优先搜索遍历类似于树的先根遍历,是树的先跟遍历的推广。假设初始状态是图中所有顶点未曾被访问,则深度优先搜索可从图中某个顶点 v 出发, 访问此顶点,然后依次从 v 的未被访问的邻接点出发深度优先遍历图,甚至图中所有和 v 相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。4、图的广度遍历广度优先遍历类似于树的按层次遍历过程。假设从图中某顶点 v 出发,在访问了 v 之后依次访问 v 的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先与

3、“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图中尚有顶点未被访问,则另选图中一个曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。五、模块划分一、基于邻接矩阵的深广度遍历1Status InitQueue(LinkQueue *Q)根据已知 Q 初始化队列2Status QueueEmpty (LinkQueue Q)判断队列是否为空3Status EnQueue(LinkQueue *Q, QElemType e)将 e 压入队尾4Status DeQueue(LinkQueue *Q, QElemType *e)取队头元素 e5

4、int LocateVex(MGraph G,VertexType v)定位定点 v6void CreateGraph(MGraph *G)建立无向图的邻接矩阵7void PrintGraph(MGraph G)输出邻接矩阵的无向图8int FirstAdjVex(MGraph G,int v)第一个邻接点的定位9int NextAdjVex(MGraph G,int v,int w)查找下一个邻接点wilyes11 收集 博客(与学习无关) :http:/ Dfs(MGraph G, int v)实现图的一次遍历11void DfsTraverse(MGraph G)实现图的深度遍历12vo

5、id BfsTraverse(MGraph G)实现图的广度遍历13Main主函数 二、基于邻接表实现图的深广度遍历1Status InitQueue(LinkQueue *Q)根据已知 Q 初始化队列2Status QueueEmpty (LinkQueue Q)判断队列是否为空3Status EnQueue(LinkQueue *Q, QElemType e)将 e 压入队尾4Status DeQueue(LinkQueue *Q, QElemType *e)取队头元素 e5void createALGraph(ALGraph *G)建立无向图的邻接矩阵6void PrintGraph(M

6、Graph G)输出邻接矩阵的无向图7int FirstAdjVex(MGraph G,int v)第一个邻接点的定位8int NextAdjVex(MGraph G,int v,int w)查找下一个邻接点9void Dfs(MGraph G, int v)实现图的一次深度遍历10void DfsTraverse(MGraph G)实现图的深度遍历11void BFS(ALGraph G, int v)实现图的一次广度遍历12void BfsTraverse(MGraph G)实现图的广度遍历13Void Main主函数 wilyes11 收集 博客(与学习无关) :http:/ struc

7、t ArcCell VRType adj; /*图中有 1/0 表示是否有边,网中表示边上的权值*/* InfoType *info; 与边相关的信息*/ ArcCell, AdjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;typedef struct VertexType vexsMAX_VERTEX_NUM; /*顶点向量*/AdjMatrix arcs; /*邻接矩阵*/int vexnum,arcnum; /*图中当前顶点数和边数*/ MGraph;2、基于邻接表的图的类型定义typedef struct ArcNode int adjvex;struct A

8、rcNode *nextarc; ArcNode; /*表节点*/ typedef struct TElemType data;ArcNode *firstarc;VNode,AdjListMAXVER; /*表节点*/typedef struct AdjList vertices;int vexnum,arcnum; /*图中当前顶点数和边数*/ ALGraph;七、源程序一、基于邻接矩阵的图的深度、广度遍历#include “stdlib.h“#include “stdio.h“#include “string.h“wilyes11 收集 博客(与学习无关) :http:/ TRUE 1#

9、define FALSE 0#define OVERFLOW -2#define OK 1#define ERROR 0typedef int Status;#define INFINITY INT_MAX /*最大值“无穷”*/#define MAX_VERTEX_NUM 20 /*最大顶点个数*/typedef int Boolean;typedef char VertexType20;typedef int VRType;/*以下为队列的操作*/*队列的类型定义*/typedef int QElemType;typedef struct QNodeQElemType data;struc

10、t QNode *next; QNode, *QueuePtr;typedef structQueuePtr front;QueuePtr rear; LinkQueue;/*初始化队列*/Status InitQueue(LinkQueue *Q) (*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode);if(!(*Q).front) exit(OVERFLOW);(*Q).front-next=NULL;return OK; /*判断队列是否为空*/Status QueueEmpty (LinkQueue Q) if (Q.front=Q.r

11、ear)return TRUE;elsereturn FALSE; /*入队列*/Status EnQueue(LinkQueue *Q, QElemType e)wilyes11 收集 博客(与学习无关) :http:/ QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode);if (!p) exit(OVERFLOW);p-data=e; p-next=NULL;(*Q).rear-next=p;(*Q).rear=p;return OK; /*出队列*/Status DeQueue(LinkQueue *Q, QElemType *e) QueuePtr

12、p;if (*Q).front=(*Q).rear) return ERROR;p=(*Q).front-next;*e=p-data;(*Q).front-next=p-next;if (*Q).rear=p) (*Q).rear=(*Q).front;free(p);return OK; /*以下为图的操作*/*图的类型定义*/typedef struct ArcCell VRType adj; /*图中有 1/0 表示是否有边,网中表示边上的权值*/* InfoType *info; 与边相关的信息*/ ArcCell, AdjMatrixMAX_VERTEX_NUMMAX_VERTEX

13、_NUM;typedef struct VertexType vexsMAX_VERTEX_NUM; /*顶点向量*/AdjMatrix arcs; /*邻接矩阵*/int vexnum,arcnum; /*图中当前顶点数和边数*/ MGraph;/* 顶点在顶点向量中的定位*/int LocateVex(MGraph G,VertexType v) int i;for(i=0;ivexnum;i+) /*输出顶点向量*/puts(G-vexsi);for(i=0;i=0; w=NextAdjVex(G,v,w)if(!visitedw) Dfs(G,w);void DfsTraverse(M

14、Graph G) int v;for (v=0; v=0; w=NextAdjVex(G,u,w)if (!visitedw) visitedw=TRUE;printf(“%s“,G.vexsw);EnQueue(wilyes11 收集 博客(与学习无关) :http:/ int w;MGraph G;CreateGraph(PrintGraph(G);printf(“nDfs:“); DfsTraverse(G); /* 深度遍历 */printf(“nBfs:“); BfsTraverse(G); /* 广度遍历 */二:基于邻接表的图的深度、广度遍历#include “stdlib.h“

15、#include “stdio.h“#include “string.h“#define MAXVER 21#define N 100typedef char TElemType10;/*循环队列的操作*/*队列的类型定义*/typedef int ElemType;typedef struct ElemType *base;int front,rear;SqQueue;/*初始化队列*/void InitQueue(SqQueue *Q)Q-base=(ElemType *)malloc(N*sizeof(ElemType);Q-front=Q-rear=0; /*判断队列是否为空*/int

16、 QueueEmpty(SqQueue Q)if(Q.front=Q.rear)return 1;elsereturn 0;wilyes11 收集 博客(与学习无关) :http:/ EnQueue(SqQueue *Q,ElemType e)if(Q-rear+1)%N=Q-front)return 0;Q-baseQ-rear=e;Q-rear=(Q-rear+1)%N;return 1;/*出队列*/int DeQueue(SqQueue *Q,ElemType *e)if(Q-rear=Q-front)return 0;*e=Q-baseQ-front;Q-front=(Q-front

17、+1)%N;return 1;/*图的操作*/*图的类型定义*/typedef struct ArcNode int adjvex;struct ArcNode *nextarc; ArcNode; typedef struct TElemType data;ArcNode *firstarc;VNode,AdjListMAXVER;typedef struct AdjList vertices;int vexnum,arcnum; ALGraph;/*建立无向图的邻接矩阵*/void createALGraph(ALGraph *G)int i, s, d;ArcNode *p,*q;pri

18、ntf(“nInput MG vexnum,arcnum:“);wilyes11 收集 博客(与学习无关) :http:/ printf(“n 输入第%d 个顶点信息:“,i); scanf(“%s“,G-verticesi.data);G-verticesi.firstarc=NULL; /输入第 i 个结点值并初始化第 i 个单链表为空 for(i=1; iarcnum; i+) printf(“n 输入第%d 条边的始点和终点:“,i);scanf(“%d,%d“,p=(ArcNode*)malloc(sizeof(ArcNode); p-adjvex=d;p-nextarc=G-ver

19、ticess.firstarc;G-verticess.firstarc=p;/将新建的以 d 为信息的表结点 p 插入 s 单链表的头结点后q=(ArcNode*)malloc(sizeof(ArcNode); q-adjvex=s;q-nextarc=G-verticesd.firstarc;G-verticesd.firstarc=q;/将新建的以 s 为信息的表结点 q 插入 d 单链表的头结点后/*深度遍历*/int visitedMAXVER;/定义全局数组遍历 visitedvoid dfs(ALGraph G, int v)/被遍历的图 G 采用邻接表作为存储结构,v 为出发顶

20、点编号 ArcNode *p;printf(“%s“,G.verticesv.data);visitedv=1;p=G.verticesv.firstarc;while(p!=NULL)if(visitedp-adjvex=0) dfs(G,p-adjvex);/若 p 所指表结点对应的邻接顶点未访问则递归地从该顶点出发调用 dfsp=p-nextarc;void dfsTraverse(ALGraph G) int v;wilyes11 收集 博客(与学习无关) :http:/ vadjvex=0) v=p-adjvex;printf(“%s“,G.verticesv.data);visit

21、edv=1;EnQueue(p=p-nextarc;void BFSTraverse(ALGraph G)int v;/遍历 G 以前,初始化 visited 数组为 0for(v=1;v=G.vexnum;v+)visitedv=0;for(v=1;v=G.vexnum;v+)if(visitedv=0)wilyes11 收集 博客(与学习无关) :http:/ main()ALGraph G;createALGraph(printf(“深度遍历结果为:n“);dfsTraverse(G);printf(“n 广度遍历结果为:n“);BFSTraverse(G);system(“pause“

22、); 八、测试情况程序的测试结果如下:1、基于邻接矩阵的图的深度、广度遍历结果正确2、基于邻接表的图的深度、广度遍历wilyes11 收集 博客(与学习无关) :http:/ 数据结构 C 语言 ,清华大学出版社。2、谭浩强, c 语言程序设计 ,清华大学出版社。wilyes11 收集 博客(与学习无关) :http:/ “自然”的起始点;其次,图中任意顶点均有可能与其它顶点相邻,在沿着某一路径依次搜索访问顶点时完全有可能又回到该顶点上;此外,图中某一顶点可能与多个顶点相邻,当访问过该结点后,如何选择下一个要访问的顶点,就成为一个决策问题。鉴于图的遍历的复杂性,遍历算法的设计就必须考虑图的结构

23、特征。图的遍历算法通常有两条遍历路径:深度优先遍历和广度优先遍历。通过学习了图的深度遍历和广度遍历,我们对邻接表和邻接矩阵进行深度遍历和广度遍历。图的深度遍历类似于树的先根遍历,广度遍历类似于树的层次遍历。在实际中,由于在图中各个结点的度数各个不同,最大度数和最小度数可能相差很多,如果按度数最大的顶点设计结点结构,就会浪费很多存储单元,反之,若按每个顶点自己的度数设计不同的结点结构,又会给操作带来不便。在实际应用中不宜采用这种结构,而应该根据具体的图和需要进行的操作,设计恰当的结点结构和表结构,这时我们就用邻接表来处理,邻接表是图的一种链式存储结构。在邻接表中,对图的每个顶点建立一个单链表,第

24、 i 个单链表中的结点表示依附于顶点 vi 的边(对有向图是以 vi 为尾的弧) 。图遍历的过程实质上是对每个顶点查找其邻接点的过程,是通过边或弧找邻接点的过程在邻接表中,对图的每个顶点建立一个单链表,第 i 个单链表中的结点表示依附于顶点 vi 的边(对有向图是以 vi 为尾的弧) 。 邻接表中每一个表结点有两个域,其一为邻接点域 adjvex,用以存放与顶点 vi 相邻接的顶点 vj 的序号 j,其二为指针域 next,用来将邻接表的所有结点链在一起。如果要表示边上的权值,那么就要再增设一个数据域。另外,为每个顶点 vi 的邻接表设置一个具有两个域的表头结点:一个域是顶点信息域 verte

25、x,另一个则是指针域(指向邻接表)link,它是 vi 的邻接表的头指针。为了便于随机访问任一顶点的邻接表,需要把这 n 个表头指针用一个一维数组存储起来,其中第 i 个分量存储 vi 邻接表的表头指针 邻接表中每一个表结点有两个域,其一为邻接点域 adjvex,用以存放与顶点 vi 相邻接的顶点 vj 的序号 j,其二为指针域 next,用来将邻接表的所有结点链在一起。如果要表示边上的权值,那么就要再增设一个数据域。另外,为每个顶点 vi 的邻接表设置一个具有两个域的表头结点:一个域是顶点信息域 vertex,另一个则是指针域(指向邻接表)link,它是 vi 的邻接表的头指针。为了便于随机

26、访问任一顶点的邻接表,需要把这 n 个表头指针用一个一维数组存储起来,其中第 i 个分量存储 vi 邻接表的表头指针。 ,一个图的邻接表不是唯一的,因为在每个顶点的邻接表中,各边结点的链接次序可以是任意的,其具体链接次序与边的输入次序和生成算法有关。 ,一个图的邻接表不是唯一的,因为在每个顶点的邻接表中,各边结点的链接次序可以是任意的,其具体链接次序与边的输入次序和生成算法有关。广度遍历图的时间复杂度和深度遍历相同,两者不同之处仅仅在于对顶点访问的顺序不同。这两种遍历既适用于无向图,也适用于有向图。但无论何种算法都是建立在邻接表存储结构之上所展开的。经过这次的程序设计让我们对邻接表和邻接矩阵有了更深度的了解,更对深度遍历和广度遍历的应用有了确切的明白,在以后的编程中也知道如何正确的运用。

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

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

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


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

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

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