数据结构学习—图的遍历
2023-06-13 09:18:56 时间
深度优先搜索(DFS)
深度优先搜索 基本思想:
- 从图中某个顶点
出发,首先访问
;
- 找出刚访问过的顶点的第一个未被访问的邻接点,然后访问该顶点。以该顶点为新顶点,重复此步骤,直到刚访问过的顶点没有 未被访问过 的邻接点为止;
- 访问前一个访问过的且仍有未被访问的临界二店的顶点,找出该顶点的下一个未被访问的邻接点,访问该顶点,然后执行2;
- 若是非连通图,则图中一定还有顶点未被访问,要从图中另选一个未被访问的顶点作为起始点,重复上述过程。 整个过程类似于树的前序遍历。
广度优先搜索(BFS)
深度优先搜索 基本思想:
- 从图中某个顶点
出发,首先访问
;
- 依次访问
各个未被访问的邻接点;
- 分别从这些邻接点出发,依次访问它们的各个未被访问的邻接点。访问时应保证:如果
和
为当前端节点,且
在
之前被访问,则
的所有未被访问的邻接点应在
所有未被访问的邻接点之前访问。重复上述过程,直到所有端节点均没有未被访问的邻接点为止。
BFS算法实现思想
- 访问出发点
并置访问标志,然后将
入队;
- 只要队不空,则重复下述处理:
- 队头节点v出队
- 对v的所有邻接点m,如果m未被访问,则访问m并置访问标志,然后m入队
邻接矩阵存储的图遍历
#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int Boolean;
typedef char VertexType;
typedef int EdgeType;
#define MAXSIZE 9
#define MAXEDGE 15
#define MAXVEX 9
#define INFINITY 65535
typedef struct //图的结构定义
{
VertexType vexs[MAXVEX]; //顶点表
EdgeType arc[MAXVEX][MAXVEX]; //邻接矩阵,边表
int numVertexes, numEdges; //图中节点数、边数
}MGraph;
typedef struct //循环队列结构
{
int data[MAXSIZE];
int front;
int rear;
}Queue;
Status InitQueue(Queue *Q) //队列初始化
{
Q->front=0;
Q->rear=0;
return OK;
}
Status QueueEmpty(Queue Q) //队列置空
{
if(Q.front==Q.rear)
return TRUE;
else
return FALSE;
}
Status EnQueue(Queue *Q,int e) //队列插入元素
{
if ((Q->rear+1)%MAXSIZE == Q->front)
return ERROR;
Q->data[Q->rear]=e;
Q->rear=(Q->rear+1)%MAXSIZE;
return OK;
}
Status DeQueue(Queue *Q,int *e) //出队
{
if (Q->front == Q->rear)
return ERROR;
*e=Q->data[Q->front];
Q->front=(Q->front+1)%MAXSIZE;
return OK;
}
void CreateMGraph(MGraph *G) //建表
{
int i, j;
G->numEdges=15; //图的顶点数、边数
G->numVertexes=9;
G->vexs[0]='A'; //定义图的顶点
G->vexs[1]='B';
G->vexs[2]='C';
G->vexs[3]='D';
G->vexs[4]='E';
G->vexs[5]='F';
G->vexs[6]='G';
G->vexs[7]='H';
G->vexs[8]='I';
for (i = 0; i < G->numVertexes; i++) //初始化图
{
for ( j = 0; j < G->numVertexes; j++)
{
G->arc[i][j]=0;
}
}
G->arc[0][1]=1; //设置边
G->arc[0][5]=1;
G->arc[1][2]=1;
G->arc[1][8]=1;
G->arc[1][6]=1;
G->arc[2][3]=1;
G->arc[2][8]=1;
G->arc[3][4]=1;
G->arc[3][7]=1;
G->arc[3][6]=1;
G->arc[3][8]=1;
G->arc[4][5]=1;
G->arc[4][7]=1;
G->arc[5][6]=1;
G->arc[6][7]=1;
for(i = 0; i < G->numVertexes; i++) //邻接矩阵是对称矩阵
{
for(j = i; j < G->numVertexes; j++)
{
G->arc[j][i] =G->arc[i][j];
}
}
}
Boolean visited[MAXVEX]; //是否被访问过的标志
void DFS(MGraph G, int i) //深度优先搜索
{
int j;
visited[i] = TRUE;
printf("%c ", G.vexs[i]);
for(j = 0; j < G.numVertexes; j++)
if(G.arc[i][j] == 1 && !visited[j])
DFS(G, j);
}
void DFSTraverse(MGraph G)
{
int i;
for(i = 0; i < G.numVertexes; i++)
visited[i] = FALSE;
for(i = 0; i < G.numVertexes; i++)
if(!visited[i])
DFS(G, i);
}
void BFSTraverse(MGraph G)
{
int i, j;
Queue Q;
for(i = 0; i < G.numVertexes; i++)
visited[i] = FALSE;
InitQueue(&Q);
for(i = 0; i < G.numVertexes; i++)
{
if (!visited[i])
{
visited[i]=TRUE;
printf("%c ", G.vexs[i]);
EnQueue(&Q,i);
while(!QueueEmpty(Q))
{
DeQueue(&Q,&i);
for(j=0;j<G.numVertexes;j++)
{
if(G.arc[i][j] == 1 && !visited[j])
{
visited[j]=TRUE;
printf("%c ", G.vexs[j]);
EnQueue(&Q,j);
}
}
}
}
}
}
int main(void)
{
MGraph G;
CreateMGraph(&G);
printf("\n深度遍历:");
DFSTraverse(G);
printf("\n广度遍历:");
BFSTraverse(G);
return 0;
}
相关文章
- vue遍历数组对象foreach_js遍历对象数组
- Java遍历JsonObject对象「建议收藏」
- Linux C++ 遍历文件夹
- .NET性能优化-快速遍历List集合
- 二叉树的层序遍历
- 前端工程师leetcode算法之二叉树的构造和遍历
- 软件测试|UI遍历的初步尝试
- L2-006 树的遍历 (25 分)
- 自监督、半监督和有监督全涵盖,四篇论文遍历对比学习的研究进展
- 【Groovy】集合遍历 ( 使用集合的 find 方法查找集合元素 | 闭包中使用 == 作为查找匹配条件 | 闭包中使用 is 作为查找匹配条件 | 闭包使用 true 作为条件 | 代码示例 )
- 【Groovy】集合遍历 ( 集合中有集合元素时调用 flatten 函数拉平集合元素 | 代码示例 )
- MySQL树形查询:分层遍历无穷深度数据(mysql树形查询)
- 学习 Linux C 实现文件夹遍历(linuxc遍历文件夹)
- Redis中新奇的遍历Key值方式(redis遍历key值)
- PHP遍历XP文件夹下所有文件
- 遍历指定目录下的所有目录和文件的php代码
- java遍历properties文件操作指南
- C#中遍历各类数据集合的方法总结
- C语言二叉树的非递归遍历实例分析