算法系列之图--DFS

  深度优先搜索使用的策略是,只要与可能就在图中尽量“深入”。DFS总是对最近才发现的结点v出发边进行探索,知道该结点的所有出发边都被发现为止。一旦v的所有出发边都被发现了,搜索就回溯到v的前驱结点(v是经该结点才被发现的),来搜索该前驱结点的出发边。该过程持续知道从源结点可以到达的所有结点都被发现为止。此后若还存在未被发现的结点,则DFS将从从未被发现的结点中任选一个结点作为新的源节点,并重复同样的过程。

  还是老办法,上代码,可以清楚地解释:

 1 #include <iostream>
 2 #include <list>
 3 using namespace std;
 4
 5 class Graph{
 6 private:
 7     int v;//结点数
 8     list<int>* adj;//结点临接链表
 9     void DFSUtil(int u,bool visited[]);
10 public:
11     Graph(int v);
12     void addEdge(int start,int end);
13     void DFS();
14 };
15
16 Graph::Graph(int v){
17     this->v = v;
18     adj = new list<int>[v];
19 }
20
21 //无向图
22 void Graph::addEdge(int start,int end){
23     adj[start].push_back(end);
24     adj[end].push_back(start);
25 }
26
27 void Graph::DFSUtil(int u,bool visited[]){
28     visited[u] = true;
29     cout<<u<<" ";
30     list<int>::iterator beg = adj[u].begin();
31     for (;beg != adj[u].end();++beg){
32         if (visited[*beg] == false)
33             DFSUtil(*beg,visited);
34     }
35 }
36
37 void Graph::DFS(){
38     bool* visited = new bool[v];
39     for (int i=0;i<v;i++)
40         visited[i] = false;
41     //递归调用dfsutil函数深度遍历每个结点
42     for (int i=0;i<v;i++)
43         if (visited[i] == false)
44             DFSUtil(i,visited);
45     cout<<endl;
46 }
47
48 int main()
49 {
50     Graph g = Graph(8);
51     g.addEdge(0,1);
52     g.addEdge(0,2);
53     g.addEdge(0,5);
54     g.addEdge(1,3);
55     g.addEdge(2,3);
56     g.addEdge(2,4);
57     g.addEdge(2,5);
58     g.addEdge(4,5);
59     g.addEdge(6,7);
60     g.DFS();
61
62     return 0;
63 }

需要指出的是,本例使用的是无向图,但DFS也可以针对有向图。

需要加以说明的是,即使该图中有结点无法保证能到达图中所有结点,但代码中第42行可以保证图中每个结点都会被访问到。

运行结果如下:

文献引用:算法导论->22章->基本图算法

代码参考:http://www.geeksforgeeks.org/depth-first-traversal-for-a-graph/

时间: 2024-12-28 13:17:13

算法系列之图--DFS的相关文章

算法系列之图--拓扑排序

本文介绍使用深度先搜索对向无环图(DAG)进行拓扑排序. 对于一个有向无环图G=(V,E)来说,其拓扑排序是G中所有结点的一种线性次序,该次序满足如下条件:如果G包含边(u,v)则结点u在拓扑排序中处于结点v的前面(若图G包含一个环路则不可能排出一个线性次序).可将图中的拓扑排序看成是将图的所有结点在一条水平线上排开,图中所有边都从左指向右. 给一个拓扑图如下示: 拓扑排序算法与DFS相似,但是在拓扑排序的过程中,每个结点都是后与其临接链表里的结点而放入Stack中. 具体代码如下示: 1 #i

算法系列之图--BFS

广度优先搜索以源结点s为出发点,算法始终将已发现和未发现结点之间的边界,沿其广度方向向外扩展.也即算法需要在发现所有距离源结点s为k的所有结点之后才会去发现距离源结点距离为k+1的其他结点. talk is cheap,show me the code!上具体的代码,最容易解释这一切. 该例子是以无向图为基础,代码中注释有具体说明,不在解释每一步: 1 #include <iostream> 2 #include <list> 3 #include <queue> 4

算法系列001---dfs理解

1.研究范围 1)多叉树,图的遍历 2)回溯法的解空间树=多叉树的遍历 2.研究方法 我们现在研究的是多叉树的遍历,固然要从二叉树的遍历开始,然后研究为什么不能直接用二叉树的遍历方法,找到多叉树不同于二叉树的地方,并对其进行解决,就得到了我们的多叉树的遍历方法. 2.1 从二叉树和多叉树|图的结构和二叉树的dfs特点及应用范围来研究 1)二叉树 public class TreeNode {  int val; TreeNode left; TreeNode right;   TreeNode(

玩转算法系列--图论精讲 面试升职必备(Java版)

第1章 和bobo老师一起,玩转图论算法欢迎大家来到我的新课程:<玩转图论算法>.在这个课程中,我们将一起完整学习图论领域的经典算法,培养大家的图论建模能力.通过这个课程的学习,你将能够真正地,玩转图论算法:) 第2章 图的基本表示千里之行,驶于足下.解决任何有一个图论算法问题,首先需要用基本的数据结构来表示图.在这一章,我们就将探索图的基本表示问题,学习邻接矩阵和邻接表,进而,也让同学们熟悉这个课程的整体代码风格. 第3章 图的深度优先遍历任何一种数据结构,都需要进行遍历.图也不例外.通过深

算法系列之二十三:离散傅立叶变换之音频播放与频谱显示

算法系列之二十三:离散傅立叶变换之音频播放与频谱显示 算法系列之二十三离散傅立叶变换之音频播放与频谱显示 导语 什么是频谱 1 频谱的原理 2 频谱的选择 3 频谱的计算 显示动态频谱 1 实现方法 2 杂项说明 结果展示 导语 频谱和均衡器,几乎是媒体播放程序的必备物件,没有这两个功能的媒体播放程序会被认为不够专业,现在主流的播放器都具备这两个功能,foobar 2000的十八段均衡器就曾经让很多人着迷.在上一篇对离散傅立叶变换介绍的基础上,本篇就进一步介绍一下频谱是怎么回事儿,下一篇继续介绍

趣写算法系列之--匈牙利算法(真的很好理解)

[书本上的算法往往讲得非常复杂,我和我的朋友计划用一些简单通俗的例子来描述算法的流程] 匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法. -------等等,看得头大?那么请看下面的版本: 通过数代人的努力,你终于赶上了剩男剩女的大潮,假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每个人都可能对多名异性有好感(-_-

白话经典算法系列之七 堆与堆排序

堆排序与高速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先解说下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是全然二叉树或者是近似全然二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)不论什么一个子节点的键值. 2.每一个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于不论什么一个子节点的键值时为最大堆.当父结点的键值总是小于或等于不论什么一个子节点的键值时为最小堆.下图展示一个最小堆

【从零学习经典算法系列】分治策略实例——二分查找

1.二分查找算法简介 二分查找算法是一种在有序数组中查找某一特定元素的搜索算法.搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束:如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较.如果在某一步骤数组 为空,则代表找不到.这种搜索算法每一次比较都使搜索范围缩小一半.折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn). 二分查找的优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且

数据结构与算法系列 目录

最近抽空整理了"数据结构和算法"的相关文章.在整理过程中,对于每种数据结构和算法分别给出"C"."C++"和"Java"这三种语言的实现:实现语言虽不同,但原理如出一辙.因此,读者在了解和学习的过程中,择其一即可! 下面是整理数据数据和算法的目录表,对于每一种按照C/C++/Java进行了划分,方便查阅.若文章有错误或纰漏,请不吝指正.谢谢! 数据结构和算法目录表   C C++ Java 线性结构 1. 数组.单链表和双链表