热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数据结构之图的深度优先搜索

数据结构之图的深度优先搜索,Go语言社区,Golang程序员人脉社

下面来讲一下图的深度优先搜索的方法。

遍历原则

从图中某一个指定的顶点v出发,先访问v,然后从该顶点未被访问过的邻接顶点w出发进行深度优先搜索,直到图中与v想通的所有顶点都被访问,此时相当于完成图中一个包含顶点v的连通分量的遍历。如果图中存在尚未遍历过的顶点,则从另一个未被访问的顶点出发重复上述过程,直到图中所有顶点均被遍历到。

显然,深度优先搜索算法是一种递归算法

分析:

假设有一幅图,如下图所示。


该图的邻接表为:


如果对该图进行深度优先搜索,步骤如下:

STEP1:从顶点A出发进行深度优先搜索。首先访问顶点A,并将A标注为已访问状态(图中标注为黄色),然后去找顶点A的第一个邻接点,如果第一个邻接点已被访问,则搜索顶点A的下一个邻接点。显然,顶点A的第一个邻接点为顶点B,且B未被访问。

STEP2:访问顶点B,并将B标注为已访问状态(图中标注为绿色),然后寻找顶点B的第一个邻接点,该邻接点为A,但是由于顶点A已经被访问过,因此继续寻找顶点B的下一个邻接点C,发现顶点C未被访问过。


STEP3:访问顶点C,并将C标注为已访问状态(图中标注为橙色),寻找C的第一个邻接点B,因为B已经被访问,因此寻找下一个邻接点D,D未被访问过。


STEP4:访问顶点D,并将D标注为已访问状态(图中标注为蓝色),寻找D的第一个邻接点A,A已经被访问过,不断寻找D的下一个邻接点,知道找到第一个未被访问的顶点E。


STEP5:访问顶点E,并将E标注为已访问状态(图中标注为红色),访问E的第一个邻接点D,发现D已经被访问过,然后去找E的下一个邻接点,发现没有邻接点,则返回上一层,也就是STEP4。


STEP6:寻找顶点D的下一个未被访问的邻接点F,访问顶点F,并将F标注为已访问状态(图中标注为紫色)。寻找F的第一个邻接点D,发现D已经被访问过,寻找F的下一个邻接点,发现没有邻接点,则返回上一层,也就是STEP4。


STEP7:寻找顶点D的未被访问的邻接点,发现不存在这样的邻接点,则返回STEP3层;寻找顶点C的未被访问的邻接点,发现不存在这样的邻接点,则返回STEP2层;寻找顶点B的未被访问的邻接点,发现不存在这样的邻接点,则返回STEP1层;寻找顶点A的未被访问的邻接点,发现不存在这样的邻接点,则退出程序。此时,图中各个顶点的访问便结束了。

代码:

1.定义图的顶点结构体VLink以及边的结构体ELink,并设置一个数组visited,该数组用来标记顶点是否被访问。例如:若visited[0]=0,说明下标为0的顶点未被访问,若visited[3]=1,说明下标为3的顶点被访问了。

#define MAXNUM 100
int visited[MAXNUM];

typedef struct edge {
	int adjvex;
	edge* next;
}ELink;

typedef struct ver {
	char vertex;
	ELink* link;
}VLink;

2.定义深度优先搜索的主算法。

void TRAVER_DFS(VLink G[], int vSize, int visited[]) {
	//初始化访问数组
	for(int i=0; i

3.定义深度优先搜索DFS算法。

void DFS( VLink G[], int v ) {
	int w;
	cout <


4.定义寻找顶点v的第一个邻接点的函数FirstADJ

int FirstADJ( VLink G[], int v ) {
	ELink *p = G[v].link;
	if(p) {
		return p->adjvex;
	}
	else {
		return -1;
	}
}
5.定义寻找顶点v的下一个未被访问的邻接点的函数NextADJ

int NextADJ( VLink G[], int v ) {
	ELink *p = G[v].link;
	while(p) {
		if(visited[p->adjvex] == 0) {
			return p->adjvex;
		}
		p = p->next;
	}
	return -1;
}

6.定义打印图的邻接表的函数

void printADJLIST(VLink G[], int vSize) {
	ELink *p;
	for(int i=0; i" <adjvex;
			p = p->next;
		}
		cout <

7.定义主函数

int _tmain(int argc, _TCHAR* argv[])
{
	VLink vArray[6];
	for(int i=0; i<6; i++) {
		vArray[i].vertex = 'A' + i;
		vArray[i].link = NULL;
	}
	ELink* edge1 = new ELink;
	ELink* edge2 = new ELink;
	ELink* edge3 = new ELink;
	ELink* edge4 = new ELink;
	ELink* edge5 = new ELink;
	ELink* edge6 = new ELink;
	ELink* edge7 = new ELink;
	ELink* edge8 = new ELink;
	ELink* edge9 = new ELink;
	ELink* edge10 = new ELink;
	ELink* edge11 = new ELink;
	ELink* edge12 = new ELink;
	edge1->adjvex = 1; edge1->next = edge2;
	edge2->adjvex = 3; edge2->next = NULL;
	edge3->adjvex = 0; edge3->next = edge4;
	edge4->adjvex = 2; edge4->next = NULL;
	edge5->adjvex = 1; edge5->next = edge6;
	edge6->adjvex = 3; edge6->next = NULL;
	edge7->adjvex = 0; edge7->next = edge8;
	edge8->adjvex = 2; edge8->next = edge9;
	edge9->adjvex = 4; edge9->next = edge10;
	edge10->adjvex = 5; edge10->next = NULL;
	edge11->adjvex = 3; edge11->next = NULL;
	edge12->adjvex = 3; edge12->next = NULL;
	vArray[0].link = edge1;
	vArray[1].link = edge3;
	vArray[2].link = edge5;
	vArray[3].link = edge7;
	vArray[4].link = edge11;
	vArray[5].link = edge12;

	printADJLIST(vArray, 6);
	TRAVER_DFS(vArray, 6, visited);

	delete edge1;
	delete edge2;
	delete edge3;
	delete edge4;
	delete edge5;
	delete edge6;
	delete edge7;
	delete edge8;
	delete edge9;
	delete edge10;
	delete edge11;
	delete edge12;
	return 0;
}

输出结果如下:



推荐阅读
author-avatar
ht遨游遐想
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有