【算法导论】图的深度优先搜索遍历(DFS)

简介:         关于图的存储在上一篇文章中已经讲述,在这里不在赘述。下面我们介绍图的深度优先搜索遍历(DFS)。         深度优先搜索遍历实在访问了顶点vi后,访问vi的一个邻接点vj;访问vj之后,又访问vj的一个邻接点,依次类推,尽可能向纵深方向搜索,所以称为深度优先搜索遍历。

        关于图的存储在上一篇文章中已经讲述,在这里不在赘述。下面我们介绍图的深度优先搜索遍历(DFS)。

        深度优先搜索遍历实在访问了顶点vi后,访问vi的一个邻接点vj;访问vj之后,又访问vj的一个邻接点,依次类推,尽可能向纵深方向搜索,所以称为深度优先搜索遍历。显然这种搜索方法具有递归的性质。图的BFS和树的搜索遍历很类似,只是其存储方式不同。

        其基本思想为:从图中某一顶点vi出发,访问此顶点,并进行标记,然后依次搜索vi的每个邻接点vj;若vj未被访问过,则对vj进行访问和标记,然后依次搜索vj的每个邻接点; 若vj的邻接点未被访问过,则访问vj的邻接点,并进行标记,直到图中和vi有路径相通的顶点都被访问。若图中尚有顶点未被访问过(非连通的情况下),则另选图中的一个未被访问的顶点作为出发点,重复上述过程,直到图中所有顶点都被访问为止。

在下面的程序中,假设图如下所示:


A B C D E对应的序号分别为0 1 2 3 4.上图的轨迹为一种深度优先搜索遍历。

具体的程序实现如下:

#include<stdio.h>
#include<stdlib.h>
#define N 5

typedef struct 
{
	char vexs[N];//顶点数组
	int arcs[N][N];//邻接矩阵
}graph;

//图的两种存储方法的结构体
typedef struct Node
{
	int adjvex;
	struct Node *next;
}edgenode;

typedef struct
{
	char vertex;
	edgenode *link;
}vexnode;

//队列的结构体
typedef struct node
{
	int data;
	struct node *next;
}linklist;

typedef struct
{
	linklist *front,*rear;
}linkqueue;

void DFS_matrix(graph g,int i,int visited[N]);//图按照邻接矩阵存储时的深度优先搜索遍历
void DFS_AdjTable(vexnode ga[N],int i,int visited[N]);//图按照邻接矩表存储时的深度优先搜索遍历


void SetNull(linkqueue *q)//置空
{
	q->front=(linklist *)malloc(sizeof(linklist));
	q->front->next=NULL;
	q->rear=q->front;
}

int Empty(linkqueue *q)//判空
{
	if(q->front==q->rear)
		return 1;
	else 
		return 0;
}

int Front(linkqueue *q)//取队头元素
{
	if(Empty(q))
	{
		printf("queue is empty!");
		return -1;
	}
	else
		return q->front->next->data;
}

void ENqueue(linkqueue *q,int x)//入队
{
	linklist * newnode=(linklist *)malloc(sizeof(linklist));
    q->rear->next=newnode;
	q->rear=newnode;
	q->rear->data=x;
	q->rear->next=NULL;
	
}

int DEqueue(linkqueue *q)//出队
{
	int temp;
	linklist *s;
	if(Empty(q))
	{
		printf("queue is empty!");
		return -1;
	}
	else
	{
		s=q->front->next;
		if(s->next==NULL)
		{
			q->front->next=NULL;
			q->rear=q->front;
		}
		else
			q->front->next=s->next;
		temp=s->data;
		return temp;
	}
}



void CreateAdjTable(vexnode ga[N],int e)//创建邻接表
{
	int i,j,k;
	edgenode *s;
	printf("\n输入顶点的内容:");
	for(i=0;i<N;i++)
	{
		//scanf("\n%c",ga[i].vertex);
		
		ga[i].vertex=getchar();
		
		ga[i].link=NULL;//初始化
	}
	printf("\n");
	for(k=0;k<e;k++)
	{
		printf("输入边的两个顶点的序号:");
		scanf("%d%d",&i,&j);//读入边的两个顶点的序号
		s=(edgenode *)malloc(sizeof(edgenode));
		s->adjvex=j;
		s->next=ga[i].link;
		ga[i].link=s;

		s=(edgenode *)malloc(sizeof(edgenode));
		s->adjvex=i;
		s->next=ga[j].link;
		ga[j].link=s;

	}
}


void main()
{
	graph g;
	int visited[5]={0};//初始化
	int visited1[5]={0};
	g.vexs[0]='A';
	g.vexs[1]='B';
	g.vexs[2]='C';
	g.vexs[3]='D';
	g.vexs[4]='E';
	int a[5][5]={{0,1,0,1,1},{ 1,0,1,0,1},{ 0,1,0,0,0},{ 1,0,0,0,0},{ 1,1,0,0,0}};
	for(int i=0;i<5;i++)
		for(int j=0;j<5;j++)
			g.arcs[i][j]=a[i][j];
	printf("图按照邻接矩阵存储时的深度优先搜索遍历:\n");
	DFS_matrix(g,0,visited);
	vexnode ga[N];
	CreateAdjTable(ga,5);//5为边的条数
		printf("图按照邻接表存储时的深度优先搜索遍历:\n");
    DFS_AdjTable(ga,0,visited1);//0为开始的顶点的序号


}

void DFS_matrix(graph g,int i,int visited[N])
{
	printf("%c\n",g.vexs[i]);
	visited[i]=1;
	for(int j=0;j<N;j++)
		if(g.arcs[i][j]==1&&visited[j]==0)//是否有未被访问的邻接点
			DFS_matrix(g,j,visited);//递归
}

void DFS_AdjTable(vexnode ga[N],int i,int visited[N])
{
	edgenode *p;
	printf("%c\n",ga[i].vertex);
	visited[i]=1;
	p=ga[i].link;
	while(p!=NULL)//p是否为空
	{
		if(visited[p->adjvex]==0)
			DFS_AdjTable(ga,p->adjvex,visited);
		p=p->next;
	}
}

其结果如下:


从上面可以看出,两种方式的结果不同,但都是正确的,因为这与邻接点访问的顺序有关。


注:如果程序出错,可能是使用的开发平台版本不同,请点击如下链接: 解释说明


原文:http://blog.csdn.net/tengweitw/article/details/17248643

作者:nineheadedbird


目录
相关文章
|
3月前
|
机器学习/深度学习 算法 C++
【DFS/回溯算法】2016年蓝桥杯真题之路径之谜详解
题目要求根据城堡北墙和西墙箭靶上的箭数,推断骑士从西北角到东南角的唯一路径。每步移动时向正北和正西各射一箭,同一格不重复经过。通过DFS回溯模拟“拔箭”过程,验证路径合法性。已知箭数约束路径唯一,最终按编号输出行走顺序。
|
9月前
|
人工智能 运维 算法
基于 C# 深度优先搜索算法的局域网集中管理软件技术剖析
现代化办公环境中,局域网集中管理软件是保障企业网络高效运行、实现资源合理分配以及强化信息安全管控的核心工具。此类软件需应对复杂的网络拓扑结构、海量的设备信息及多样化的用户操作,而数据结构与算法正是支撑其强大功能的基石。本文将深入剖析深度优先搜索(Depth-First Search,DFS)算法,并结合 C# 语言特性,详细阐述其在局域网集中管理软件中的应用与实现。
222 3
|
4月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
302 3
|
10月前
|
监控 算法 安全
基于 PHP 语言深度优先搜索算法的局域网网络监控软件研究
在当下数字化时代,局域网作为企业与机构内部信息交互的核心载体,其稳定性与安全性备受关注。局域网网络监控软件随之兴起,成为保障网络正常运转的关键工具。此类软件的高效运行依托于多种数据结构与算法,本文将聚焦深度优先搜索(DFS)算法,探究其在局域网网络监控软件中的应用,并借助 PHP 语言代码示例予以详细阐释。
222 1
|
11月前
|
运维 监控 JavaScript
内网网管软件中基于 Node.js 的深度优先搜索算法剖析
内网网管软件在企业网络中不可或缺,涵盖设备管理、流量监控和安全防护。本文基于Node.js实现深度优先搜索(DFS)算法,解析其在网络拓扑遍历中的应用。通过DFS,可高效获取内网设备连接关系,助力故障排查与网络规划。代码示例展示了图结构的构建及DFS的具体实现,为内网管理提供技术支持。
237 11
|
11月前
|
机器学习/深度学习 算法
算法系列之搜索算法-深度优先搜索DFS
深度优先搜索和广度优先搜索一样,都是对图进行搜索的算法,目的也都是从起点开始搜索,直到到达顶点。深度优先搜索会沿着一条路径不断的往下搜索,直到不能够在继续为止,然后在折返,开始搜索下一条候补路径。
869 62
算法系列之搜索算法-深度优先搜索DFS
|
10月前
|
算法 安全 Java
算法系列之深度优先搜索寻找妖怪和尚过河问题的所有方式
在算法学习中,深度优先搜索(DFS)是一种常用的图搜索算法,通过递归或栈实现,适合路径搜索、连通性、拓扑排序、回溯、生成、环路检测、强连通分量和可达性等问题。本文将介绍如何利用深度优先搜索解决“妖怪和尚过河问题”的所有方式。
221 26
算法系列之深度优先搜索寻找妖怪和尚过河问题的所有方式
|
10月前
|
监控 算法 JavaScript
企业用网络监控软件中的 Node.js 深度优先搜索算法剖析
在数字化办公盛行的当下,企业对网络监控的需求呈显著增长态势。企业级网络监控软件作为维护网络安全、提高办公效率的关键工具,其重要性不言而喻。此类软件需要高效处理复杂的网络拓扑结构与海量网络数据,而算法与数据结构则构成了其核心支撑。本文将深入剖析深度优先搜索(DFS)算法在企业级网络监控软件中的应用,并通过 Node.js 代码示例进行详细阐释。
209 2
|
10月前
|
存储 算法 JavaScript
基于 Node.js 深度优先搜索算法的上网监管软件研究
在数字化时代,网络环境呈现出高度的复杂性与动态性,上网监管软件在维护网络秩序与安全方面的重要性与日俱增。此类软件依托各类数据结构与算法,实现对网络活动的精准监测与高效管理。本文将深度聚焦于深度优先搜索(DFS)算法,并结合 Node.js 编程语言,深入剖析其在上网监管软件中的应用机制与效能。
153 6
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
580 3