图采用邻接矩阵存储结构

合集下载

图-存储结构-数组表示法(邻接矩阵)

图-存储结构-数组表示法(邻接矩阵)

图-存储结构-数组表⽰法(邻接矩阵)⽂字描述 ⽤两个数组分别存储顶点信息和边/弧信息。

⽰意图算法分析 构造⼀个采⽤邻接矩阵作存储结构、具有n个顶点和e条边的⽆向⽹(图)G的时间复杂度是(n*n + e*n), 其中对邻接矩阵G.arcs的初始化耗费了n*n的时间。

借助于邻接矩阵容易判定两个顶点之间是否有边/弧相连,并容易求得各个顶点的度。

对于⽆向图,顶点vi的度是邻接矩阵地i⾏(或第i列)的元素之和;对于有向图,第i⾏的元素之和为顶点vi的出度;第j列的元素之和为顶点vj的⼊度;代码实现1/*2以数组表⽰法(邻接矩阵)作为图的存储结构创建图。

3*/4 #include <stdio.h>5 #include <stdlib.h>6 #include <string.h>78#define INFINITY 100000 //最⼤值9#define MAX_VERTEX_NUM 20 //最⼤顶点数10 typedef enum {DG, DN, UDG, UDN} GraphKind; //{有向图,有向⽹,⽆向图,⽆向⽹}11 typedef int VRType;12 typedef char VertexType;13 typedef struct{14char note[10];15 }InfoType;16 typedef struct ArcCell{17 VRType adj; //顶点关系类型:1)对⽆权图,⽤1或0表⽰相邻否;2)对带权图,则为权值类型18 InfoType *info; //该弧相关信息的指针19 }ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];20 typedef struct{21 VertexType vexs[MAX_VERTEX_NUM]; //顶点向量22 AdjMatrix arcs; //邻接矩阵23int vexnum, arcnum; //图的当前顶点数和弧数24 GraphKind kind; //图的种类标志25 }MGraph;2627/*28若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。

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

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

实现图的邻接矩阵和邻接表存储1.需求分析对于下图所示的有向图G,编写一个程序完成如下功能:1.建立G的邻接矩阵并输出之2.由G的邻接矩阵产生邻接表并输出之3.再由2的邻接表产生对应的邻接矩阵并输出之2.系统设计1.图的抽象数据类型定义:ADT Graph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集数据关系R:R={VR}VR={<v,w>|v,w∈V且P(v,w),<v,w>表示从v到w的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}基本操作P:CreatGraph(&G,V,VR)初始条件:V是图的顶点集,VR是图中弧的集合操作结果:按V和VR的定义构造图GDestroyGraph(&G)初始条件:图G存在操作结果:销毁图GInsertVex(&G,v)初始条件:图G存在,v和图中顶点有相同特征操作结果:在图G中增添新顶点v……InsertArc(&G,v,w)初始条件:图G存在,v和w是G中两个顶点操作结果:在G中增添弧<v,w>,若G是无向的则还增添对称弧<w,v>……DFSTraverse(G,Visit())初始条件:图G存在,Visit是顶点的应用函数操作结果:对图进行深度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。

一旦Visit()失败,则操作失败BFSTraverse(G,Visit())初始条件:图G存在,Visit是顶点的应用函数操作结果:对图进行广度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。

一旦Visit()失败,则操作失败}ADT Graph2.主程序的流程:调用CreateMG函数创建邻接矩阵M;调用PrintMatrix函数输出邻接矩阵M调用CreateMGtoDN函数,由邻接矩阵M创建邻接表G调用PrintDN函数输出邻接表G调用CreateDNtoMG函数,由邻接表M创建邻接矩阵N调用PrintMatrix函数输出邻接矩阵N3.函数关系调用图:3.调试分析(1)在MGraph的定义中有枚举类型typedef enum{DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网}赋值语句G.kind(int)=M.kind(GraphKind);是正确的,而反过来M.kind=G.kind则是错误的,要加上那个强制转换M.kind=GraphKind(G.kind);枚举类型enum{DG,DN,UDG,UDN}会自动赋值DG=0;DN=1,UDG=2,UDN=3;可以自动从GraphKind类型转换到int型,但不会自动从int型转换到GraphKind类型(2)算法的时间复杂度分析:CreateMG、CreateMGtoDN、CreateDNtoMG、PrintMatrix、PrintDN的时间复杂度均为O(n2) n为图的顶点数,所以main:T(n)= O(n2)4.测试结果用需求分析中的测试数据输入:输出:5、用户手册(1)输入顶点数和弧数;(2)输入顶点内容;(3)按行序输入邻接矩阵,输入各弧相应权值(4)回车输出邻接矩阵M、邻接表G和邻接矩阵N6、附录源程序:#include <stdio.h>#include <stdlib.h>#define MAX_VERTEX_NUM 20typedef int VRType;typedef int InfoType;typedef int VertexType;typedef enum{DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网} typedef struct ArcCell{VRType adj;//VRType是顶点关系类型,对无权图用1或0表示是否相邻;//对带权图则为权值类型InfoType *info;//该弧相关信息的指针}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct{VertexType vexs[MAX_VERTEX_NUM];//顶点向量AdjMatrix arcs;//邻接矩阵int vexnum,arcnum;//图的当前顶点数和弧数GraphKind kind;//图的种类标志}MGraph;void CreateMG(MGraph &M){int i,j;M.kind=DN;printf("输入顶点数:");scanf("%d",&M.vexnum);printf("输入弧数:");scanf("%d",&M.arcnum);printf("输入顶点:\n");for(i=0;i<M.vexnum;i++)scanf("%d",&M.vexs[i]);printf("建立邻接矩阵:\n");for(i=0;i<M.vexnum;i++)for(j=0;j<M.vexnum;j++)scanf("%d",&M.arcs[i][j].adj);printf("输入相应权值:\n");for(i=0;i<M.vexnum;i++)for(j=0;j<M.vexnum;j++)if(M.arcs[i][j].adj){scanf("%d",&M.arcs[i][j].info);}}typedef struct ArcNode{int adjvex;//该弧所指向的顶点在数组中的下标struct ArcNode *nextarc;InfoType *info;//该弧相关信息的指针}ArcNode;typedef struct VNode{VertexType data;//顶点信息ArcNode *firstarc;//指向第一条依附该顶点的弧的指针}VNode,AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arcnum;//图的当前顶点数和弧数int kind;//图的种类标志}ALGraph;void PrintDN(ALGraph G){int i;ArcNode *p;printf("顶点:\n");for(i=0;i<G.vexnum;++i)printf("%2d",G.vertices[i].data);printf("\n弧:\n");for(i=0;i<G.vexnum;++i){p=G.vertices[i].firstarc;while(p){printf("%d→%d(%d)\t",i,p->adjvex,p->info);p=p->nextarc;}printf("\n");}//for}void CreateMGtoDN(ALGraph &G,MGraph M){//采用邻接表存储表示,构造有向图G(G.kind=DN)int i,j;ArcNode *p;G.kind=M.kind;G.vexnum=M.vexnum;G.arcnum=M.arcnum;for(i=0;i<G.vexnum;++i){//构造表头向量G.vertices[i].data=M.vexs[i];G.vertices[i].firstarc=NULL;//初始化指针}for(i=0;i<G.vexnum;++i)for(j=0;j<G.vexnum;++j)if(M.arcs[i][j].adj==1){p=(ArcNode*)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G.vertices[i].firstarc;p->info=M.arcs[i][j].info;G.vertices[i].firstarc=p;}}void CreateDNtoMG(MGraph &M,ALGraph G){int i,j;ArcNode *p;M.kind=GraphKind(G.kind);M.vexnum=G.vexnum;M.arcnum=G.arcnum;for(i=0;i<M.vexnum;++i)M.vexs[i]=G.vertices[i].data;for(i=0;i<M.vexnum;++i){p=G.vertices[i].firstarc;while(p){M.arcs[i][p->adjvex].adj=1;p=p->nextarc;}//whilefor(j=0;j<M.vexnum;++j)if(M.arcs[i][j].adj!=1)M.arcs[i][j].adj=0;}//for}void PrintMatrix(MGraph M){ int i,j;for(i=0;i<M.vexnum;++i){for(j=0;j<M.vexnum;++j) printf("%2d",M.arcs[i][j].adj); printf("\n");}}void main(){MGraph M,N;ALGraph G; CreateMG(M);PrintMatrix(M); CreateMGtoDN(G,M); PrintDN(G); CreateDNtoMG(N,G); PrintMatrix(N);}。

《数据结构》第八章习题参考答案 (1)

《数据结构》第八章习题参考答案 (1)
邻接表表示时:无向图的任意顶点的度=顶点所对应边结点链表中结点个数;
有向图的任意顶点的度=邻接表中顶点所对应边链表中结点个数+逆邻接表中顶点所对应边链表中结点个数;
4、课本P3928.3题
【解答】
n个顶点的无向连通图至少有n-1条边,n个பைடு நூலகம்点的无向强连通图至少有n(n-1)/2条边;n个顶点的有向连通图至少有n条边,n个顶点的有向强连通图至少有n(n-1)条边。
上面不正确的是(A)。
A.(1),(2),(3) B.(1) C.(1),(3) D.(2),(3)
5、下列说法不正确的是(C)。
A.图的遍历是从给定的源点出发每一个顶点仅被访问一次
B.遍历的基本算法有两种:深度遍历和广度遍历
C.图的深度遍历不适用于有向图
D.图的深度遍历是一个递归过程
三、填空题
1、判断一个无向图是一棵树的条件是_有n个顶点,n-1条边的无向连通图_。
注: 答案并不唯一
2、课本P3928.1题
【解答】
(1)不是强连通图
(2)简单路径如:D->B->C->F
(3)略
(4)邻接表见图,其他略
3、课本P3928.2题
【解答】
(1)邻接矩阵表示:无向图的边数为
矩阵中非零元素的个数/2;有向图的边数为矩阵中非零元素的个数。
邻接表表示时:无向图的边数为邻接表中边结点的个数/2;有向图的边数为邻接表中边结点的个数。
(2)(3)略
12、课本P3958.24题
【解答】
A->B : 10
A->B->D: 15
A->B->D->C : 17
A->B->D->E : 17

图的常用存储结构

图的常用存储结构

图的常⽤存储结构⼀、邻接矩阵 邻接矩阵是简单的也是⽐较常⽤的⼀种表⽰图的数据结构,对于⼀个有N个点的图,需要⼀个N*N的矩阵,这个矩阵的i⾏第j列的数值表⽰点vi到点vj的距离。

邻接矩阵需要初始化,map[i][i] = 0;map[i][j] = INF(i != j),对于每组读⼊的数据vi,vj,w(vi为边的起点,vj为边的终点,w为边的权值),赋值map[vi][vj] = w,另外邻接矩阵的值和边的输⼊顺序⽆关。

对于邻接矩阵来说,初始化需要O(n^2)的时间,建图需要O(m),所以总时间复杂度是O(n^2),空间上,邻接矩阵的开销也是O(n^2),和点的个数有关。

⼆、前向星 前向星是⼀种通过存储边的⽅式来存储图的数据结构。

构造的时候,只需要读⼊每条边的信息,将边存放在数组中,把数组中的边按照起点顺序排序,前向星就构造完毕,为了查询⽅便,经常会有⼀个数组存储起点为vi的第⼀条边的位置. 由于涉及排序,前向星的构造时间复杂度与排序算法有关,⼀般情况下时间复杂度为O(mlogN),空间上需要两个数组,所以空间复杂度为O(m + n),有点在于可以应对点⾮常多的情况,可以存储重边,但是不能直接判断任意两个顶点之间是否有边.1 #include <iostream>2 #include <cmath>3 #include <cstdio>4 #include <cstring>5 #include <cstdlib>6 #include <algorithm>7using namespace std;8 typedef long long LL;910const int MAXN = 1000 + 3;11int head[MAXN]; //存储起点为Vi的边第⼀次出现的位置1213struct NODE14 {15int from;16int to;17int w;18 };19 NODE edge[MAXN];2021bool cmp(NODE a, NODE b)22 {23if(a.from == b.from && a.to == b.to) return a.w < b.w;24if(a.from == b.from) return a.to < b.to;25return a.from < b.from;26 }2728int main()29 {30 freopen("input.txt", "r", stdin);31int n,m;32 cin >> n >> m;33for(int i = 0; i < m; i++)34 {35 cin >> edge[i].from >> edge[i].to >> edge[i].w;36 }37 sort(edge, edge + m, cmp);38 memset(head, -1, sizeof(head));39 head[edge[0].from] = 0;40for(int i = 1; i < m; i++)41 {42if(edge[i].from != edge[i - 1].from)43 {44 head[edge[i].from] = i;45 }46 }47for(int i = 1; i <= n; i++)48 {49for(int k = head[i]; edge[k].from == i && k < m; k++)50 {51 cout << edge[k].from << '' << edge[k].to << '' << edge[k].w <<endl;52 }53 }54for(int i = 0; i <= n; i++)55 {56 cout << head[i] << "";57 }58 cout << endl;59return0;60 }三、链式前向星 链式前向星采⽤数组模拟链表的⽅式实现邻接表的功能,并且使⽤很少的额外空间,是当前建图和遍历效率最⾼的存储⽅式.数组模拟链表的主要⽅式是记录下⼀个节点的数组的在哪⼀个位置。

数据结构 第7章习题答案

数据结构 第7章习题答案

第7章 《图》习题参考答案一、单选题(每题1分,共16分)( C )1. 在一个图中,所有顶点的度数之和等于图的边数的 倍。

A .1/2 B. 1 C. 2 D. 4 (B )2. 在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的 倍。

A .1/2 B. 1 C. 2 D. 4 ( B )3. 有8个结点的无向图最多有 条边。

A .14 B. 28 C. 56 D. 112 ( C )4. 有8个结点的无向连通图最少有 条边。

A .5 B. 6 C. 7 D. 8 ( C )5. 有8个结点的有向完全图有 条边。

A .14 B. 28 C. 56 D. 112 (B )6. 用邻接表表示图进行广度优先遍历时,通常是采用 来实现算法的。

A .栈 B. 队列 C. 树 D. 图 ( A )7. 用邻接表表示图进行深度优先遍历时,通常是采用 来实现算法的。

A .栈 B. 队列 C. 树 D. 图 ()8. 已知图的邻接矩阵,根据算法思想,则从顶点0出发按深度优先遍历的结点序列是( D )9. 已知图的邻接矩阵同上题8,根据算法,则从顶点0出发,按深度优先遍历的结点序列是A . 0 2 4 3 1 5 6 B. 0 1 3 5 6 4 2C. 0 4 2 3 1 6 5D. 0 1 2 34 6 5 ( D )10. 已知图的邻接表如下所示,根据算法,则从顶点0出发按深度优先遍历的结点序列是( A )11. 已知图的邻接表如下所示,根据算法,则从顶点0出发按广度优先遍历的结点序列是A .0 2 4 3 1 5 6B. 0 1 3 6 5 4 2C. 0 1 3 4 2 5 6D. 0 3 6 1 5 4 2⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡0100011101100001011010110011001000110010011011110A .0 1 3 2 B. 0 2 3 1 C. 0 3 2 1 D. 0 1 2 3(A)12. 深度优先遍历类似于二叉树的A.先序遍历 B. 中序遍历 C. 后序遍历 D. 层次遍历(D)13. 广度优先遍历类似于二叉树的A.先序遍历 B. 中序遍历 C. 后序遍历 D. 层次遍历(A)14. 任何一个无向连通图的最小生成树A.只有一棵 B. 一棵或多棵 C. 一定有多棵 D. 可能不存在(注,生成树不唯一,但最小生成树唯一,即边权之和或树权最小的情况唯一)二、填空题(每空1分,共20分)1. 图有邻接矩阵、邻接表等存储结构,遍历图有深度优先遍历、广度优先遍历等方法。

数据结构课程设计-图的邻接矩阵

数据结构课程设计-图的邻接矩阵

数据结构课程设计报告设计题目:图的邻接矩阵存储结构院系计算机学院年级x 级学生xxxx学号xxxxxxxxxx指导教师xxxxxxxxx起止时间10-6/10-102013年10月10日目录1 需求分析 (3)2 概要设计 (4)2.1 ADT描述 (4)2.2程序模块结构 (5)2.3各功能模块 (6)3详细设计 (7)3.1类的定义 (7)3.2 初始化 (8)3.3 图的构建操作 (8)3.4 输出操作 (9)3.5 get操作 (9)3.6 插入操作 (10)3.7 删除操作 (10)3.8 求顶点的度操作 (11)3.10 判断连通操作 (12)3.11 主函数 (13)4 调试分析 (16)4.1调试问题 (16)4.2 算法时间复杂度 (16)5用户手册 (16)5.1 主界面 (16)5.2 创建图 (17)5.3插入节点 (17)5.4 深度优先遍历 (17)5.5 求各顶点的度 (18)5.6 输出图 (18)5.7 判断是否连通 (19)5.8 求边的权值 (19)5.9 插入边 (19)5.10 删除边 (20)结论 (20)参考文献 (20)摘要随着计算机的普及,涉及计算机相关的科目也越来越普遍,其中数据结构是计算机专业重要的专业基础课程与核心课程之一,为适应我国计算机科学技术的发展和应用,学好数据结构非常必要,然而要掌握数据结构的知识非常难,所以对“数据结构”的课程设计比不可少。

本说明书是对“无向图的邻接矩阵存储结构”课程设计的说明。

首先是对需求分析的简要阐述,说明系统要完成的任务和相应的分析,并给出测试数据。

其次是概要设计,说明所有抽象数据类型的定义、主程序的流程以及各程序模块之间的层次关系,以及ADT描述。

然后是详细设计,描述实现概要设计中定义的基本功操作和所有数据类型,以及函数的功能及代码实现。

再次是对系统的调试分析说明,以及遇到的问题和解决问题的方法。

然后是用户使用说明书的阐述,然后是测试的数据和结果的分析,最后是对本次课程设计的结论。

2013吉林省数据库考试含答案基础

2013吉林省数据库考试含答案基础

1、假设以邻接矩阵作为图的存储结构,编写算法判别在给定的有向图中是否存在一个简单有向回路,若存在,则以顶点序列的方式输出该回路(找到一条即可)。

(注:图中不存在顶点到自己的弧)有向图判断回路要比无向图复杂。

利用深度优先遍历,将顶点分成三类:未访问;已访问但其邻接点未访问完;已访问且其邻接点已访问完。

下面用0,1,2表示这三种状态。

前面已提到,若dfs(v)结束前出现顶点u到v的回边,则图中必有包含顶点v和u的回路。

对应程序中v的状态为1,而u是正访问的顶点,若我们找出u的下一邻接点的状态为1,就可以输出回路了。

void Print(int v,int start ) //输出从顶点start开始的回路。

{for(i=1;i<=n;i++)if(g[v][i]!=0 && visited[i]==1 ) //若存在边(v,i),且顶点i的状态为1。

{printf(“%d”,v);if(i==start) printf(“\n”); else Print(i,start);break;}//if}//Printvoid dfs(int v){visited[v]=1;for(j=1;j<=n;j++ )if (g[v][j]!=0) //存在边(v,j)if (visited[j]!=1) {if (!visited[j]) dfs(j); }//ifelse {cycle=1; Print(j,j);}visited[v]=2;}//dfsvoid find_cycle() //判断是否有回路,有则输出邻接矩阵。

visited数组为全局变量。

{for (i=1;i<=n;i++) visited[i]=0;for (i=1;i<=n;i++ ) if (!visited[i]) dfs(i);}//find_cycle2、设T是一棵满二叉树,编写一个将T的先序遍历序列转换为后序遍历序列的递归算法。

邻接表 和邻接矩阵

邻接表 和邻接矩阵

邻接表和邻接矩阵
邻接表和邻接矩阵是表示图的两种常用数据结构,它们用于描述图中各个顶点之间的连接关系。

具体分析如下:
- 邻接表:邻接表是一种链表数组,其中每个数组元素对应一个顶点,并且包含一个链表,链表中的每个节点代表与该顶点相邻的顶点。

这种结构特别适合于表示稀疏图,即边的数量远小于顶点数量的平方的图。

在邻接表中,对于每个顶点,只需要存储与其直接相连的顶点,因此可以节省空间。

当图的顶点较多,且图为稀疏图时,邻接表通常是更合适的选择。

- 邻接矩阵:邻接矩阵是一种二维数组,其中行和列都代表图中的顶点。

如果两个顶点之间存在边,则相应的矩阵元素值为1(或者边的权重,如果是带权图),否则为0。

邻接矩阵适用于表示稠密图,即边的数量接近顶点数量的平方的图。

邻接矩阵的优点是可以快速地判断任意两个顶点之间是否存在边,但是当图非常稀疏时,它会占用较多的内存空间。

总的来说,邻接表和邻接矩阵各有优势,选择哪种数据结构取决于具体的应用场景。

如果图是稀疏的,并且需要节省存储空间,邻接表通常更合适;如果需要快速查询任意两点之间的关系,而图又相对稠密,邻接矩阵可能是更好的选择。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

图采用邻接矩阵存储结构#define TRUE 1#define FALSE 0#define MAXV 20typedef int V ertexType; //用顶点编号表示顶点typedef struct { // 图的定义int edges[MAXV][MAXV] ; // 边数组int n, e; //顶点数,弧数V ertexType vexs[MAXV]; // 顶点信息} MGraph;1、创建具有n个顶点e条边的无向图void CreateUDG(MGraph &G,int n,int e){int i,j,u,v;G.n=n;G.e=e;/*printf("请输入%d个顶点的编号:\n",n);for(i=0;i<n;i++)scanf("%d",&G.vexs[i]);*///初始化顶点信息,假设顶点的编号和顶点在数组内的下标相同for(i=0;i<n;i++)G.vexs[i]=i;//初始化邻接矩阵for(i=0;i<n;i++)for(j=0;j<n;j++)G.edges[i][j]=0;for(j=0;j<e;j++){printf("请输入一条边的两个顶点编号:");scanf("%d%d",&u,&v);G.edges[u][v]=G.edges[v][u]=1;}}2、创建具有n个顶点e条弧的有向图void CreateDG(MGraph &G,int n,int e){int i,j,u,v;G.n=n;G.e=e;/*printf("请输入%d个顶点的编号:\n",n);for(i=0;i<n;i++)scanf("%d",&G.vexs[i]);*///初始化顶点信息,假设顶点的编号和顶点在数组内的下标相同for(i=0;i<n;i++)G.vexs[i]=i;//初始化邻接矩阵for(i=0;i<n;i++)for(j=0;j<n;j++)G.edges[i][j]=0;for(j=0;j<e;j++){printf("请输入一条弧的两个顶点编号(注意先输入的为弧尾):"); scanf("%d%d",&u,&v);G.edges[u][v]=1;}}3、求图G中顶点v的第一个邻接点int FirstAdjV ex(MGraph G, int v){for(int i=0;i<G.n;i++)if(G.edges[v][i]==1)return i;return -1;}4、求图G中顶点v相对于w的下一个邻接点int NextAdjV ex(MGraph G, int v,int w){for(int i=w;i<G.n;i++)if(G.edges[v][i]==1)return i;return -1;}5、深度优先搜索算法Boolean visited[MAXV];void DFSTravse (MGraph G){// 对图 G 作深度优先遍历。

for (v=0; v<G.vexnum; ++v)visited[v] = FALSE; // 访问标志数组初始化for (v=0; v<G.vexnum; ++v)if (!visited[v]) DFS(G, v);// 对尚未访问的顶点调用DFS}void DFS(MGraph G, int v) {// 从顶点v出发,深度优先搜索遍历连通图 Gvisited[v] = TRUE; printf(v);for(int w=FirstAdjV ex(G, v);w>=0; w=NextAdjV ex(G,v,w))if (!visited[w]) DFS(G, w);// 对v的尚未访问的邻接顶点w// 递归调用DFS} // DFS6、广度优先搜索算法void BFSTraverse(MGraph G){for (v=0; v<G.vexnum; ++v)visited[v] = FALSE; //初始化访问标志InitQueue(Q); // 置空的辅助队列Qfor ( v=0; v<G.vexnum; ++v )if ( !visited[v]){ // v 尚未访问visited[v] = TRUE; printf(v); // 访问vEnQueue(Q, v); // v入队列while (!QueueEmpty(Q)){DeQueue(Q, u); // 队头元素出队并置为ufor(w=FirstAdjV ex(G, u); w>=0; w=NextAdjV ex(G,u,w)) if ( ! visited[w]){visited[w]=TRUE; printf(w);EnQueue(Q, w); // 访问的顶点w入队列} // if} // while} //if} // BFS图采用邻接表存储结构typedef struct ANode /*弧(边)的结点结构类型*/{ int adjvex; /*该弧(边)的终点位置*/struct ANode *nextarc; /*指向下一条弧(边)的指针*/} ArcNode;typedef struct Vnode /*邻接表头结点的类型*/{ V ertexType data; /*顶点信息*/ArcNode *firstarc; /*指向第一条弧(边)*/} VNode;typedef VNode AdjList[MAXV]; /*AdjList是邻接表类型*/typedef struct{ AdjList adjlist; /*邻接表*/int n,e; /*图中顶点数n和边数e*/} ALGraph; /*图的类型*/1、创建具有n个顶点e条边的无向图void CreateUDG(ALGraph &G,int n,int e){int i,j,u,v;ArcNode *p1,*p2,*q;G.n=n;G.e=e;//初始化顶点信息(头结点),假设顶点的编号和顶点在数组内的下标相同for(i=0;i<n;i++){ G.adjlist[i].data=i; G.adjlist[i].firstarc=NULL; }//生成每个顶点的邻接点的单链表for(j=0;j<e;j++)printf("请输入一条边的两个顶点编号:");scanf("%d%d",&u,&v);p1=(ArcNode *)malloc(sizeof(ArcNode));p1->adjvex=v;p1->nextarc=NULL;if(G.adjlist[u].firstarc==NULL) G.adjlist[u].firstarc=p1;else{ q=G.adjlist[u].firstarc;while(q->nextarc!=NULL) q=q->nextarc;q->nextarc=p1;}p2=(ArcNode *)malloc(sizeof(ArcNode));p2->adjvex=u;p2->nextarc=NULL;if(G.adjlist[v].firstarc==NULL) G.adjlist[v].firstarc=p2;else{ q=G.adjlist[v].firstarc;while(q->nextarc!=NULL) q=q->nextarc;q->nextarc=p2;}}//for}2、创建具有n个顶点e条弧的有向图void CreateUDG(ALGraph &G,int n,int e){int i,j,u,v;ArcNode *p,*q;G.n=n;G.e=e;//初始化顶点信息(头结点),假设顶点的编号和顶点在数组内的下标相同for(i=0;i<n;i++){ G.adjlist[i].data=i; G.adjlist[i].firstarc=NULL; }//生成每个顶点的邻接点的单链表for(j=0;j<e;j++){printf("请输入一条弧的两个顶点编号(先输入的为弧尾):");scanf("%d%d",&u,&v);p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=v;p->nextarc=NULL;if(G.adjlist[u].firstarc==NULL) G.adjlist[u].firstarc=p; else{ q=G.adjlist[u].firstarc;while(q->nextarc!=NULL) q=q->nextarc;q->nextarc=p;}}//for}3、求图G中顶点v的第一个邻接点int FirstAdjV ex(ALGraph G, int v){ ArcNode *p=G.adjlist[v].firstarc;if(p!=NULL) return p->adjvex;else return -1;}4、求图G中顶点v相对于w的下一个邻接点int NextAdjV ex(ALGraph G, int v,int w){ ArcNode *p=G.adjlist[v].firstarc;while(p!=NULL&&p->adjvex!=w)p=p->nextarc;if(p) return p->adjvex;else return -1;}。

相关文档
最新文档