【算法导论】图的深度优先搜索遍历(DFS)
关于图的存储在上一篇文章中已经讲述,在这里不在赘述。下面我们介绍图的深度优先搜索遍历(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
【算法导论】图的深度优先搜索遍历(DFS)的更多相关文章
- 【算法导论】图的广度优先搜索遍历(BFS)
图的存储方法:邻接矩阵.邻接表 例如:有一个图如下所示(该图也作为程序的实例): 则上图用邻接矩阵可以表示为: 用邻接表可以表示如下: 邻接矩阵可以很容易的用二维数组表示,下面主要看看怎样构成邻接表: ...
- 图的深度优先搜索dfs
图的深度优先搜索: 1.将最初访问的顶点压入栈: 2.只要栈中仍有顶点,就循环进行下述操作: (1)访问栈顶部的顶点u: (2)从当前访问的顶点u 移动至顶点v 时,将v 压入栈.如果当前顶点u 不存 ...
- [算法入门]——深度优先搜索(DFS)
深度优先搜索(DFS) 深度优先搜索叫DFS(Depth First Search).OK,那么什么是深度优先搜索呢?_? 样例: 举个例子,你在一个方格网络中,可以简单理解为我们的地图,要从A点到B ...
- 采用邻接矩阵表示图的深度优先搜索遍历(与深度优先搜索遍历连通图的递归算法仅仅是DFS的遍历方式变了)
//采用邻接矩阵表示图的深度优先搜索遍历(与深度优先搜索遍历连通图的递归算法仅仅是DFS的遍历方式变了) #include <iostream> using namespace std; ...
- 深度优先搜索(DFS)
定义: (维基百科:https://en.wikipedia.org/wiki/Depth-first_search) 深度优先搜索算法(Depth-First-Search),是搜索算法的一种.是沿 ...
- 深度优先搜索(dfs)与出题感想
在3月23号的广度优先搜索(bfs)博客里,我有提到写一篇深搜博客,今天来把这个坑填上. 第一部分:深度优先搜索(dfs) 以上来自百度百科. 简单来说,深度优先搜索算法就是——穷举法,即枚举所有情况 ...
- 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现
1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...
- 深度优先搜索(DFS)和广度优先搜索(BFS)
深度优先搜索(DFS) 广度优先搜索(BFS) 1.介绍 广度优先搜索(BFS)是图的另一种遍历方式,与DFS相对,是以广度优先进行搜索.简言之就是先访问图的顶点,然后广度优先访问其邻接点,然后再依次 ...
- Leetcode之深度优先搜索(DFS)专题-130. 被围绕的区域(Surrounded Regions)
Leetcode之深度优先搜索(DFS)专题-130. 被围绕的区域(Surrounded Regions) 深度优先搜索的解题详细介绍,点击 给定一个二维的矩阵,包含 'X' 和 'O'(字母 O) ...
随机推荐
- Node.js 网络
稳定性: 3 - 稳定 net 模块提供了异步网络封装,它包含了创建服务器/客户端的方法(调用 streams).可以通过调用 require('net') 包含这个模块. net.createSer ...
- 【Java集合系列】---ArrayList
开篇前言--ArrayList中的基本方法 前面的博文中,小编主要简单介绍java集合的总体架构,在接下来的博文中,小编将详细介绍里面的各个类,通过demo.对比,来对java集合类进行更加深入的理解 ...
- 网卡配置和DNS配置,手动挂在nas存储的共享目录,网络相关其它操作命令,修改防火墙中的端口配置,resolv.conf配置详细介绍和网卡信息配置详细介绍
1. 网卡配置和DNS配置 若想服务器能够发邮件,需要让部署的服务器能够访问到外网环境.若部署的服务器访问不到外网,通过ping www.baidu.com的方式执行的时候,会出现以下问题: &q ...
- Linux动态频率调节系统CPUFreq之三:governor
在上一篇文章中,介绍了cpufreq的core层,core提供了cpufreq系统的初始化,公共数据结构的建立以及对cpufreq中其它子部件提供注册功能.core的最核心功能是对policy的管理, ...
- 全文检索 Lucene(3)
看完前两篇博客之后,想必大家对于Lucene的使用都有了一个比较清晰的认识了.如果对Lucene的知识点还是有点模糊的话,个人建议还是先看看这两篇文章. 全文检索 Lucene(1) 全文检索 Luc ...
- ROS_Kinetic_26 使用rosserial_windows实现windows与ROS master发送与接收消息
使用rosserial_windows实现windows与ROS master发送与接收消息(适用版本hydro,indigo,jade,kinetic) 官方wiki地址汇总请参考:http://b ...
- x264源代码简单分析:熵编码(Entropy Encoding)部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- Android获取当前网络状态
Android获取当前网络状态 效果图 有网络 没有网络 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q4878802/9052 ...
- [ExtJS5学习笔记]第十三节 Extjs5的Ext.each方法学习
本文地址:http://blog.csdn.net/sushengmiyan/article/details/39009555 sencha官方API:http://docs.sencha.com/e ...
- acm入门搜索-水池数目
水池数目 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上仅标识了此处 ...