分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_C语言:数据结构-图的广度优先搜索遍历...

广度优先搜索遍历

(1)广度优先搜索遍历的定义

广度优先搜索遍历类似于树的按层遍历,其遍历过程如下:

1.访问初始点vi,并将其标记已访问过,访问vi的所有未被访问过的邻接点(次序可任意),假定依次为vi1、vi2、…、vit,并均标记已访问过。

2.然后按邻接点访问的先后次序,依次访问V11,V22,……Vit所有未被访问的邻接点,直至所有顶点访问完。

(2)广度优先搜索遍历的过程

下面结合图7-10所示的有向图G8分析从v0出发进行广度优先搜索遍历的过程。

3c870b6209eee2f4f2e797683ea26743.png

1.访问初始点v0,并将其标记为已访问过;

2.访问v0的所有未被访问过的邻接点v1和v2,并将它们标记为已访问过;

3.访问顶点v1的所有未被访问过的邻接点v3、v4和v5,并将它们标记为已访问过;

4. 访问顶点v2的所有未被访问过的邻接点v6(它的两个邻接点中的一个顶点v5已被访问过),并将其标记为已访问过;

5.访问顶点v3的所有未被访问过的邻接点v7(只此一个邻接点且没有被访问过),并将其标记为已访问过;

6.访问顶点v4的所有未被访问过的邻接点,因v4的邻接点v7(只此一个)已被访问过,所以此步不访问任何顶点;

7.访问顶点v5的所有未被访问过的邻接点v8,并将其标记为已访问过;

8.访问顶点v6的所有未被访问过的邻接点,因v6的仅一个邻接点v8已被访问过,所以此步不访问任何顶点;

9. 依次访问v7和v8的所有未被访问的邻接点,因它们均没有邻接点(即出边邻接点),所以整个遍历过程到此结束。

从以上对有向图G8进行广度优先搜索遍历的过程分析可知,从初始点v0出发,得到的访问各顶点的次序为:v0,v1,v2,v3,v4,v5,v6,v7,v8

(3)广度优先搜索遍历的算法描述

在广度优先搜索遍历中,先被访问的顶点,其邻接点亦先被访问,所以在算法的实现中需要使用一个队列,用来依次记住被访问过的顶点。算法开始时,将初始点vi访问后插入队列中,以后每从队列中删除一个元素,就依次访问它的每一个未被访问过的邻接点,并令其进队,这样,当队列为空时,表明所有与初始点有路径相通的顶点都已访问完毕,算法到此结束。

下面分别以邻接矩阵和邻接表作为图的存储结构给出相应的广度优先搜索遍历的算法,同样在算法中使用的标记数组visited[MaxVertexNum]为全程量。

邻接矩阵广度优先搜索遍历算法

void bfs1(adjmatrix GA, int i, int n) /*从初始点vi出发广度优先搜索由邻接矩阵GA表示的图*/{/*定义一个顺序队列Q,其元素类型应为整型,初始化队列为空*/ int Q[MS]; //MS是一个事先定义的符号常量 int front=0, rear=0;/*访问初始点vi,同时标记初始点vi已访问过*/ printf("%d 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
邻接矩阵实现深度优先遍历广度优先遍历深度优先遍历: 1. 定义一个栈,将起始节点入栈。 2. 当栈不为空时,取出栈顶节点,访问该节点,并将其未被访问的邻居节点入栈。 3. 标记已访问的节点。 4. 重复步骤2和3,直到栈为空。 邻接矩阵实现深度优先遍历的代码: ```c #define MAX_VERTEX_NUM 100 //最大顶点数 #define INFINITY 65535 //表示无穷大 typedef struct { int vexs[MAX_VERTEX_NUM]; //顶点表 int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵 int vexnum, arcnum; //的当前顶点数和弧数 } MGraph; int visited[MAX_VERTEX_NUM]; //标记节点是否被访问过 void DFS(MGraph G, int v) { visited[v] = 1; //标记节点v已被访问 printf("%d ", G.vexs[v]); //访问节点v for (int i = ; i < G.vexnum; i++) { if (G.arcs[v][i] != INFINITY && !visited[i]) { //如果节点i是节点v的邻居且未被访问 DFS(G, i); //递归访问节点i } } } void DFSTraverse(MGraph G) { for (int i = ; i < G.vexnum; i++) { visited[i] = ; //初始化visited数组 } for (int i = ; i < G.vexnum; i++) { if (!visited[i]) { //如果节点i未被访问 DFS(G, i); //从节点i开始深度优先遍历 } } } ``` 广度优先遍历: 1. 定义一个队列,将起始节点入队。 2. 当队列不为空时,取出队首节点,访问该节点,并将其未被访问的邻居节点入队。 3. 标记已访问的节点。 4. 重复步骤2和3,直到队列为空。 邻接矩阵实现广度优先遍历的代码: ```c #define MAX_VERTEX_NUM 100 //最大顶点数 #define INFINITY 65535 //表示无穷大 typedef struct { int vexs[MAX_VERTEX_NUM]; //顶点表 int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵 int vexnum, arcnum; //的当前顶点数和弧数 } MGraph; int visited[MAX_VERTEX_NUM]; //标记节点是否被访问过 void BFS(MGraph G, int v) { int queue[MAX_VERTEX_NUM]; //定义队列 int front = , rear = ; //队首和队尾指针 visited[v] = 1; //标记节点v已被访问 printf("%d ", G.vexs[v]); //访问节点v queue[rear++] = v; //将节点v入队 while (front != rear) { //队列不为空时 int w = queue[front++]; //取出队首节点w for (int i = ; i < G.vexnum; i++) { if (G.arcs[w][i] != INFINITY && !visited[i]) { //如果节点i是节点w的邻居且未被访问 visited[i] = 1; //标记节点i已被访问 printf("%d ", G.vexs[i]); //访问节点i queue[rear++] = i; //将节点i入队 } } } } void BFSTraverse(MGraph G) { for (int i = ; i < G.vexnum; i++) { visited[i] = ; //初始化visited数组 } for (int i = ; i < G.vexnum; i++) { if (!visited[i]) { //如果节点i未被访问 BFS(G, i); //从节点i开始广度优先遍历 } } } ``` 邻接表实现深度优先遍历广度优先遍历深度优先遍历: 1. 定义一个栈,将起始节点入栈。 2. 当栈不为空时,取出栈顶节点,访问该节点,并将其未被访问的邻居节点入栈。 3. 标记已访问的节点。 4. 重复步骤2和3,直到栈为空。 邻接表实现深度优先遍历的代码: ```c #define MAX_VERTEX_NUM 100 //最大顶点数 typedef struct ArcNode { //边表节点 int adjvex; //邻接点在顶点表中的位置 struct ArcNode *nextarc; //指向下一个边表节点 } ArcNode; typedef struct VNode { //顶点表节点 int data; //顶点数据 ArcNode *firstarc; //指向第一个边表节点 } VNode, AdjList[MAX_VERTEX_NUM]; typedef struct { AdjList vertices; //邻接表 int vexnum, arcnum; //的当前顶点数和弧数 } ALGraph; int visited[MAX_VERTEX_NUM]; //标记节点是否被访问过 void DFS(ALGraph G, int v) { visited[v] = 1; //标记节点v已被访问 printf("%d ", G.vertices[v].data); //访问节点v ArcNode *p = G.vertices[v].firstarc; while (p) { if (!visited[p->adjvex]) { //如果节点p->adjvex未被访问 DFS(G, p->adjvex); //递归访问节点p->adjvex } p = p->nextarc; } } void DFSTraverse(ALGraph G) { for (int i = ; i < G.vexnum; i++) { visited[i] = ; //初始化visited数组 } for (int i = ; i < G.vexnum; i++) { if (!visited[i]) { //如果节点i未被访问 DFS(G, i); //从节点i开始深度优先遍历 } } } ``` 广度优先遍历: 1. 定义一个队列,将起始节点入队。 2. 当队列不为空时,取出队首节点,访问该节点,并将其未被访问的邻居节点入队。 3. 标记已访问的节点。 4. 重复步骤2和3,直到队列为空。 邻接表实现广度优先遍历的代码: ```c #define MAX_VERTEX_NUM 100 //最大顶点数 typedef struct ArcNode { //边表节点 int adjvex; //邻接点在顶点表中的位置 struct ArcNode *nextarc; //指向下一个边表节点 } ArcNode; typedef struct VNode { //顶点表节点 int data; //顶点数据 ArcNode *firstarc; //指向第一个边表节点 } VNode, AdjList[MAX_VERTEX_NUM]; typedef struct { AdjList vertices; //邻接表 int vexnum, arcnum; //的当前顶点数和弧数 } ALGraph; int visited[MAX_VERTEX_NUM]; //标记节点是否被访问过 void BFS(ALGraph G, int v) { int queue[MAX_VERTEX_NUM]; //定义队列 int front = , rear = ; //队首和队尾指针 visited[v] = 1; //标记节点v已被访问 printf("%d ", G.vertices[v].data); //访问节点v queue[rear++] = v; //将节点v入队 while (front != rear) { //队列不为空时 int w = queue[front++]; //取出队首节点w ArcNode *p = G.vertices[w].firstarc; while (p) { if (!visited[p->adjvex]) { //如果节点p->adjvex未被访问 visited[p->adjvex] = 1; //标记节点p->adjvex已被访问 printf("%d ", G.vertices[p->adjvex].data); //访问节点p->adjvex queue[rear++] = p->adjvex; //将节点p->adjvex入队 } p = p->nextarc; } } } void BFSTraverse(ALGraph G) { for (int i = ; i < G.vexnum; i++) { visited[i] = ; //初始化visited数组 } for (int i = ; i < G.vexnum; i++) { if (!visited[i]) { //如果节点i未被访问 BFS(G, i); //从节点i开始广度优先遍历 } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值