深度优先搜索算法在图遍历中的应用解析,C语言版

引言

在图论中,图的遍历是一项基础且重要的操作,它能帮助我们探索图中所有的顶点和边。深度优先搜索(DFS)算法是图遍历的常用方法之一,类似于树的前序遍历。本文将详细解析一个用 C 语言实现的基于邻接矩阵表示的图的深度优先搜索算法代码。

代码整体功能概述

这段代码实现了一个简单的图的深度优先搜索遍历。它首先定义了图的邻接矩阵表示结构,接着创建了一个具体的图,最后从图的第一个顶点开始进行深度优先搜索并输出遍历结果。

1. 头文件和宏定义

#include
#include

//深度优先算法(类似于前序遍历)

typedef char VertexType;	//顶点
typedef int EdgeType;		//边
#define MAXSIZE 100

  1. 头文件stdio.h 用于标准输入输出操作,stdlib.h 为标准库函数提供支持。
  2. 类型定义VertexType 被定义为 char 类型,用于表示图的顶点;EdgeType 被定义为 int 类型,用于表示图的边。
  3. 宏定义MAXSIZE 定义了图的最大顶点数量。

2. 图的邻接矩阵表示结构

typedef struct
{	
	VertexType vertex[MAXSIZE];		//0,1,2,3,
	EdgeType arc[MAXSIZE][MAXSIZE];	//用来表示顶点与边的关系,有边是1,没边是0
	int vertex_num;		//顶点数量
	int edge_num;		//边数量
}Mat_Grph;			//矩阵图

  1. vertex 数组:用于存储图的所有顶点。
  2. arc 二维数组:是邻接矩阵,arc[i][j] 为 1 表示顶点 i 和顶点 j 之间有边相连,为 0 则表示无边相连。
  3. vertex_num:记录图的顶点数量。
  4. edge_num:记录图的边数量。

3. 访问标记数组

int visited[MAXSIZE];	//记录顶点是否被访问过,0表示未被访问,1表示访问了

visited 数组用于标记每个顶点是否已经被访问过,初始值都为 0,表示所有顶点都未被访问。

4. 图的创建函数 create_graph

void create_graph(Mat_Grph* G){	
	G->vertex_num =9;
	G->edge_num = 15;
	//设置顶点
	G->vertex[0] = 'A';
	G->vertex[1] = 'B';
	G->vertex[2] = 'C';
	G->vertex[3] = 'D';
	G->vertex[4] = 'E';
	G->vertex[5] = 'F';
	G->vertex[6] = 'G';
	G->vertex[7] = 'H';
	G->vertex[8] = 'I';
	for (int i=0;i < G->vertex_num; i++){
		for (int j = 0;j < G->vertex_num; j++){
			G->arc[i][j] = 0;		//二维数组初始化
		}
	}

	//连线
	//A-B A-F
	G->arc[0][1] = 1;
	G->arc[0][5] = 1;

	//B-C B-G B-I
	G->arc[1][2] = 1;
	G->arc[1][6] = 1;
	G->arc[1][8] = 1;

	//C-D C-I
	G->arc[2][3] = 1;
	G->arc[2][8] = 1;

	//D-E D-G D-H D-I
	G->arc[3][4] = 1;
	G->arc[3][6] = 1;
	G->arc[3][7] = 1;
	G->arc[3][8] = 1;

	//E-F E-H
	G->arc[4][5] = 1;
	G->arc[4][7] = 1;

	//F-G
	G->arc[5][6] = 1;

	//G-H
	G->arc[6][7] =1;

	for (int i = 0; i < G->vertex_num; i++)
	{
		for (int j=0;jvertex_num; j++)
		{
		G->arc[j][i] = G->arc[i][j];	//把对称的另一半copy过去[0][1] = [1][0]..
		}
	}
}

  1. 初始化顶点和边的数量:设置图的顶点数量为 9,边的数量为 15。
  2. 设置顶点:将顶点 A 到 I 依次存储在 vertex 数组中。
  3. 初始化邻接矩阵:将邻接矩阵 arc 的所有元素初始化为 0,表示所有顶点之间初始时都没有边相连。
  4. 添加边:根据代码中给出的边的信息,将对应的邻接矩阵元素置为 1。
  5. 对称复制:由于无向图的邻接矩阵是对称的,所以将 arc[i][j] 的值复制到 arc[j][i]

下面是这个图的邻接矩阵表示:

A B C D E F G H I
A 0 1 0 0 0 1 0 0 0
B 1 0 1 0 0 0 1 0 1
C 0 1 0 1 0 0 0 0 1
D 0 0 1 0 1 0 1 1 1
E 0 0 0 1 0 1 0 1 0
F 1 0 0 0 1 0 1 0 0
G 0 1 0 1 0 1 0 1 0
H 0 0 0 1 1 0 1 0 0
I 0 1 1 1 0 0 0 0 0

5. 深度优先搜索函数 dfs

void dfs(Mat_Grph G, int i)		//深度优先
{
	visited[i] = 1;
	printf("%c\n", G.vertex[i]);

	for (int j = 0; j < G.vertex_num; j++)	//9次
	{
		if (G.arc[i][j] == 1 && visited[j] == 0)	//跟A有连线,并且没有被访问过
		{	
			dfs(G, j);	//递归
		}
	}
}

  1. 标记当前顶点:将当前顶点 i 标记为已访问,即 visited[i] = 1
  2. 输出当前顶点:打印当前顶点的字符表示。
  3. 递归搜索:遍历当前顶点的所有邻接顶点,如果邻接顶点未被访问过,则递归调用 dfs 函数对该邻接顶点进行深度优先搜索。

6. 主函数 main

int main(int argc, char const *argv[])
{
	Mat_Grph G;
	create_graph(&G);

	for (int i = 0; i < G.vertex_num; i++)
	{
		visited[i] = 0;		//初始化,顶点是否被访问过,0表示未被访问,1表示访问了
	}
	dfs(G, 0);	//表示第一个顶点A
	return 0;
}

  1. 创建图:调用 create_graph 函数创建图。
  2. 初始化访问标记数组:将 visited 数组的所有元素初始化为 0,表示所有顶点都未被访问。
  3. 开始深度优先搜索:从第一个顶点 A(索引为 0)开始进行深度优先搜索。

总结

深度优先搜索算法利用递归的方式,沿着一条路径尽可能深地访问顶点,直到无法继续,然后回溯到上一个顶点,继续探索其他路径

你可能感兴趣的:(数据结构,深度优先,算法,c语言,408,数据结构,开发语言)