图的遍历(深度优先遍历)

图的遍历

 

树的遍历我们谈了四种方式,大家回忆一下,树因为根结点只有一个,并且所有的结点都只有一个双亲,所以不是很难理解。

但是谈到图的遍历,那就复杂多了,因为它的任一顶点都可以和其余的所有顶点相邻接,因此极有可能存在重复走过某个顶点或漏了某个顶点的遍历过程。

 

对于图的遍历,如果要避免以上情况,那就需要科学地设计遍历方案,通常有两种遍历次序方案:它们是深度优先遍历和广度优先遍历。

 

深度优先遍历

 

深度优先遍历(DepthFirstSearch),也有称为深度优先搜索,简称为DFS。

它的具体思想类似于课程开头讲的找钥匙方案,无论从哪一间房间开始都可以,将房间内的墙角、床头柜、床上、床下、衣柜、电视柜等挨个寻找,做到不放过任何一个死角,当所有的抽屉、储藏柜中全部都找遍,接着再寻找下一个房间。

 

现在请大家一起来想办法走以下这个迷宫:

《图的遍历(深度优先遍历)》

深度优先遍历

 

我们可以约定右手原则:在没有碰到重复顶点的情况下,分叉路口始终是向右手边走,每路过一个顶点就做一个记号。

接下来有情小甲鱼童鞋带我们走迷宫去。

 

迷宫走完了,所有的顶点也遍历过了,这就是深度优先遍历!

反应快的童鞋一定会感觉深度优先遍历其实就是一个递归的过程嘛~

 

如果再细心观察,你会发现整个遍历过程就像是一棵树的前序遍历!

《图的遍历(深度优先遍历)》

// 邻接表的深度有限递归算法
#define TRUE 1
#define FALSE 0
#define MAX 256

typedef int Boolean;	// 这里我们定义Boolean为布尔类型,其值为TRUE或FALSE
Boolean visited[MAX];	// 访问标志的数组

void DFS(GraphAdjList GL, int i)
{
	EdgeNode *p;
	
	visited[i] = TRUE;
	printf("%c " 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);
		}
	}
}

// 邻接矩阵的深度有限递归算法


#define TRUE 1
#define FALSE 0
#define MAX 256

typedef int Boolean;	// 这里我们定义Boolean为布尔类型,其值为TRUE或FALSE
Boolean visited[MAX];	// 访问标志的数组

void DFS(MGraph G, int i)
{
	int j;
	
	visited[j] = TRUE;			// 访问过的顶点设置为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);
		}
	}
}
    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/zy_dreamer/article/details/9059303
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞