图 - 深度优先遍历

图的遍历和树的遍历类似,我们希望从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历(Traverse Graph)。

图的遍历方法一般有两种,第一种是深度优先遍历(Depth First Search),也有称为深度优先搜索,简称为DFS。第二种是《广度优先遍历(Breadth  First Search)》,也有称为广度优先搜索,简称为BFS。我们在《堆栈与深度优先搜索》中已经较为详细地讲述了深度优先搜索的策略,这里不再赘述。我们也可以把图当作一个迷宫,设定一个起始点,走遍所有图的顶点并打上标记,直到访问遍所有的顶点为止。如图7-5-2所示,需要注意的是结点I 是在从A->H,H->回溯->D,D->I 的时候被访问到的,而且我们是从A开始递归进入下面的路径,所以会一直回溯到原点A为止表示遍历结束。

下面只给出邻接矩阵和邻接表存储方式时的图的深度优先遍历的算法代码,没有给出整体可供测试运行的代码,其实只需要再写一个创建图的函数就可以进行整体测试了,可以参考《邻接矩阵创建图》和《邻接表创建图

一、如果我们使用的是邻接矩阵的方式,则代码如下:(改编自《大话数据结构》)

C++ Code


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

 

typedef char VertexType; /* 顶点类型应由用户定义 */

typedef int EdgeType; /* 边上的权值类型应由用户定义 */

#define MAXSIZE 9 /* 存储空间初始分配量 */

#define MAXEDGE 15

#define MAXVEX 9

typedef struct

{

VertexType vexs[MAXVEX]; /* 顶点表 */

EdgeType arc[MAXVEX][MAXVEX];/* 邻接矩阵,可看作边表 */

int numVertexes, numEdges; /* 图中当前的顶点数和边数 */

} MGraph;

bool visited[MAXVEX];/* 访问标志的数组 */

/* 邻接矩阵的深度优先递归算法 */

void DFS(MGraph MG, int i)

{

int j;

visited[i] = true;

cout << MG.vexs[i] << ‘ ‘; /* 打印顶点,也可以其它操作 */

for (j = 0; j < MG.numVertexes; j++)

if (MG.arc[i][j] == 1 && !visited[j])

DFS(MG, j);/* 对为访问的邻接顶点递归调用 */

}

/* 邻接矩阵的深度遍历操作 */

void DFSTraverse(MGraph MG)

{

int i;

for (i = 0; i < MG.numVertexes; i++)

visited[i] = false;/* 初始所有顶点状态都是未访问过状态 */

for (i = 0; i < MG.numVertexes; i++)

if (!visited[i])

DFS(MG, i);/* 对未访问过的顶点调用DFS,若是连通图,只会执行一次*/

}

遍历结果为: A B C D E F G H I (上图所示的图结构)

二、如果我们使用的是邻接表的方式,则代码如下:(改编自《大话数据结构》)

C++ Code


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

 
/* 邻接表结构****************** */

typedef struct EdgeNode /* 边表结点 */

{

int adjvex;    /* 邻接点域,存储该顶点对应的下标 */

int weight;     /* 用于存储权值,对于非网图可以不需要 */

struct EdgeNode *next; /* 链域,指向下一个邻接点 */

} EdgeNode;

typedef struct VertexNode /* 顶点表结点 */

{

int in; //结点入度

char data; /* 顶点域,存储顶点信息 */

EdgeNode *firstedge;/* 边表头指针 */

} VertexNode, AdjList[MAXVEX];

typedef struct

{

AdjList adjList;

int numVertexes, numEdges; /* 图中当前顶点数和边数 */

} graphAdjList, *GraphAdjList;

bool visited[MAXVEX];/* 访问标志的数组 */

/* 邻接表的深度优先递归算法 */

void DFS(GraphAdjList GL, int i)

{

EdgeNode *p;

visited[i] = true;

cout << GL->adjList[i].data << ‘ ‘; /* 打印顶点,也可以其它操作 */

p = GL->adjList[i].firstedge;

while (p)

{

if (!visited[p->adjvex])

DFS(GL, p->adjvex);/* 对为访问的邻接顶点递归调用 */

p = p->next;

}

}

/* 邻接表的深度遍历操作 */

void DFSTraverse(GraphAdjList GL)

{

int i;

for (i = 0; i < GL->numVertexes; i++)

visited[i] = false;/* 初始所有顶点状态都是未访问过状态 */

for (i = 0; i < GL->numVertexes; i++)

if (!visited[i])

DFS(GL, i);/* 对未访问过的顶点调用DFS,若是连通图,只会执行一次*/

}

遍历结果为:A F G H E D I C B (上图所示的图结构)

由结果可以看出,因为我们采用了不同的存储方式,即使使用的是同样的深度优先搜索,遍历的结果也是不同的。

原文地址:https://www.cnblogs.com/alantu2018/p/8471717.html

时间: 2024-10-13 08:54:22

图 - 深度优先遍历的相关文章

【暖*墟】 #树与图# 深度优先遍历入门知识点

[一. 时间戳(dfn)] 什么是时间戳? 就是每个位置被访问到的次序. 比如说我们对一棵树进行深搜,在深搜中访问的相应次序就被我们称为时间戳. [二. 树的dfs序] 1.dfs序的作用 维护一系列树上的问题,解决一棵树上的所有后代结点信息的更改和祖先结点有关改变, 通过dfs来记录树的每个顶点的出入时间戳,来控制它子树上的所有结点的状态的更新. 用 L[ i ],R[ i ] 来记录这个祖先结点控制后代结点的区间. 即dfs序的特点就是:每个节点编号x在序列中恰好出现两次. 一棵子树的dfs

数据结构(15):图 深度优先遍历(DFS)

/*-----------------------------------------------*/ /* 邻接矩阵的DFS */ // 基于 数据结构(14) 中的邻接矩阵的结构 #include <iostream> using namespace std; typedef char VertexType; typedef int EdgeType; const int MAXVEX = 100; const int INFINITY = 65535; typedef struct {

数据结构实践——迷宫问题之图深度优先遍历解法

版权声明:本文为博主原创文章,未经博主允许不得转载.

图的深度优先遍历&amp;广度优先遍历

1.什么是图的搜索? 指从一个指定顶点可以到达哪些顶点 2.图的两种存储结构 (1)邻接矩阵 原理就是用两个数组,一个一维数组保存顶点集,一个二维数组(邻接矩阵)保存边集. (2)邻接表 2.深度优先遍历

41 蛤蟆的数据结构笔记之四十一图的遍历之深度优先

41  蛤蟆的数据结构笔记之四十一图的遍历之深度优先 本篇名言:"对于我来说 , 生命的意义在于设身处地替人着想 , 忧他人之忧 , 乐他人之乐. -- 爱因斯坦" 上篇我们实现了图的邻接多重表表示图,以及深度遍历和广度遍历的代码,这次我们先来看下图的深度遍历. 欢迎转载,转载请标明出处: 1.  原理 图遍历又称图的遍历,属于数据结构中的内容.指的是从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次.图的遍历操作和树的遍历操作功能相似.图的遍历是图的一种基本操作,图的许多其它

java实现图的遍历(深度优先遍历和广度优先遍历)

package arithmetic.graphTraveral;import java.util.LinkedList;import java.util.Queue; /** * 这个例子是图的遍历的两种方式 * 通过它,使我来理解图的遍历 * Created on 2013-11-18 * @version 0.1 */public class GraphTraveral{ // 邻接矩阵存储图 // --A B C D E F G H I // A 0 1 0 0 0 1 1 0 0 //

图的深度优先遍历--邻接表实现

这里用邻接表实现图的深度优先遍历,采用递归实现. #include<iostream> using namespace std; #define VERTEXNUM 5//结点数 struct edgenode { int to; int weight; // 边的权值 edgenode *next; }; struct vnode { int from; edgenode *first; }; void createGraph(vnode *adjilist, int start, int

图的遍历(深度优先与广度优先搜索两种方案)

1.图的遍历--深度优先搜索 import java.util.Scanner ; public class Map{ static int n ; static int m ; static int[] book ; static int[][] e ; public static void mapDfs(int cur){ //深度优先搜索思想核心: System.out.print(cur + " ") ; for (int i=1;i<=n;i++) { if (e[cu

图的遍历---深度优先遍历与广度优先遍历

对下图进行遍历,分别采用深度优先和广度优先 1.深度优先遍历的主要思想:首先从一个未被访问的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点: 当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有顶点都被访问. 显然,深度优先遍历是沿着图的某一条分支遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有顶点被访问. /*深度优先搜索算法遍历图的各个顶点*/ #include<stdio.h> int n, sum, book[101]; int e[101][101