【算法导论】图的深度优先搜索遍历(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月前
|
算法 测试技术 定位技术
数据结构与算法——DFS(深度优先搜索)
数据结构与算法——DFS(深度优先搜索)
|
5月前
|
算法
DFS算法的实现
DFS算法的实现
77 3
|
2月前
|
算法
数据结构之路由表查找算法(深度优先搜索和宽度优先搜索)
在网络通信中,路由表用于指导数据包的传输路径。本文介绍了两种常用的路由表查找算法——深度优先算法(DFS)和宽度优先算法(BFS)。DFS使用栈实现,适合路径问题;BFS使用队列,保证找到最短路径。两者均能有效查找路由信息,但适用场景不同,需根据具体需求选择。文中还提供了这两种算法的核心代码及测试结果,验证了算法的有效性。
118 23
|
2月前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
2月前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
69 5
|
2月前
|
算法
树的遍历算法有哪些?
不同的遍历算法适用于不同的应用场景。深度优先搜索常用于搜索、路径查找等问题;广度优先搜索则在图的最短路径、层次相关的问题中较为常用;而二叉搜索树的遍历在数据排序、查找等方面有重要应用。
42 2
|
2月前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
57 0
|
2月前
|
算法 vr&ar 计算机视觉
数据结构之洪水填充算法(DFS)
洪水填充算法是一种基于深度优先搜索(DFS)的图像处理技术,主要用于区域填充和图像分割。通过递归或栈的方式探索图像中的连通区域并进行颜色替换。本文介绍了算法的基本原理、数据结构设计(如链表和栈)、核心代码实现及应用实例,展示了算法在图像编辑等领域的高效性和灵活性。同时,文中也讨论了算法的优缺点,如实现简单但可能存在堆栈溢出的风险等。
67 0
|
3月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
38 0
|
3月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)

热门文章

最新文章