body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

  从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历(Traversing Graph)
****注:图的建立上一篇博客《图的邻接矩阵存储实现》已经放了源代码了,这里要运行只要按代码加上相应的文件就能执行****

深度优先遍历(DFS,Depth_First_Search):
  从图中某个顶点V出发,访问此顶点,然后从V的未被访问的邻接点触犯深度优先遍历图,直至图中所有和V有路径相通的顶点都被访问到。相当于树的前序遍历。针对非连通图,只要对每个连通分量分别进行深度优先遍历,即在先前一个顶点进行一次深度优先遍历后,若图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

右图是递归遍历的过程,其实每一层都是从A结点开始搜寻满足条件的点
/* DFS.h */
#ifndef __DFS_H__
#define __DFS_H__
#include"Graph.h"
namespace meihao
{
        void DFS(const meihao::Graph& g,int vi,bool*& visited);  //参数->图和顶点数组中某个顶点的下标
        void DFSTraversal(const meihao::Graph& g);
};
#endif

/* testMain.cpp */
#include"DFS.h"
#include<iostream>
int main()
{
        meihao::Graph g("data.txt");
        meihao::DFSTraversal(g);
        cout<<endl;
        system("pause");
}


/* data.txt */
9
A B C D E F G H I
0 1 0 0 0 1 0 0 0
1 0 1 0 0 0 1 0 1
0 1 0 1 0 0 0 0 1
0 0 1 0 1 0 1 1 1
0 0 0 1 0 1 0 1 0
1 0 0 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
0 0 0 1 1 0 1 0 0
0 1 1 1 0 0 0 0 0 

/* DFS.cpp */

#include"DFS.h"
namespace meihao
{
//算法都是基于邻接矩阵实现的
        void DFS(const meihao::Graph& g,int vi,bool*& visited)
        {
                visited[vi] = true;  //修改第vi个结点的访问标记为true
                cout<<g.getGraphVertexData(vi)<<" ";
                for(int idx=0;idx!=g.getGraphVertexNumber();++idx)
                {
                        if(1==g.getGraphEdgeWeight(vi,idx)&&
                                false==visited[idx])  //如果(vi,idx)之间存在边(==1),并且第idx个顶点还没有访问过
                        {
                                DFS(g,idx,visited);  //递归遍历第idx个顶点
                        }
                }
        }
        void DFSTraversal(const meihao::Graph& g)
        {
                bool* visited = new bool[g.getGraphVertexNumber()]();
                for(int idx=0;idx!=g.getGraphVertexNumber();++idx)
                {
                        visited[idx] = false;  //初始化访问标记,全部为false,表示未访问
                }
                for(int idx=0;idx!=g.getGraphVertexNumber();++idx)
                {
                        if(false==visited[idx])  //随便选一个点,如果未访问过,就从它开始深度优先遍历
                                DFS(g,idx,visited);
                }
        }
};
广度优先遍历(Breadth First Search):
 类似于图的层序遍历,
/* BFS.h */

#ifndef __BFS_H__
#define __BFS_H__
#include"Graph.h"
namespace meihao
{
        void BFSTraversal(const meihao::Graph& g);
};
#endif

/* test.cpp */
#include"BFS.h"
#include<iostream>
int main()
{
        meihao::Graph g("data.txt");
        meihao::BFSTraversal(g);
        cout<<endl;
        system("pause");
}


/* data.txt */
9
A B C D E F G H I
0 1 0 0 0 1 0 0 0
1 0 1 0 0 0 1 0 1
0 1 0 1 0 0 0 0 1
0 0 1 0 1 0 1 1 1
0 0 0 1 0 1 0 1 0
1 0 0 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
0 0 0 1 1 0 1 0 0
0 1 1 1 0 0 0 0 0 

/* BFS.cpp */

#include"BFS.h"
#include<queue>
namespace meihao
{
        void BFSTraversal(const meihao::Graph& g)
        { //广度优先遍历相当于层序遍历
                queue<int> rootNode;  //存放图的顶点
                bool* visited = new bool[g.getGraphVertexNumber()];
                for(int idx=0;idx!=g.getGraphVertexNumber();++idx)
                {
                        visited[idx] = false;
                }
                for(int idx=0;idx!=g.getGraphVertexNumber();++idx)
                { //if语句可以确保如果图中有多个连通分量,也能每个点都访问到
                        if(false==visited[idx])  //如果该结点没有访问到
                        {
                                //访问
                                cout<<g.getGraphVertexData(idx)<<" ";
                                visited[idx] = true;
                                rootNode.push(idx);
                                while(!rootNode.empty())  //把刚刚访问到的结点的下一层结点访问并入队列
                                {
                                        for(int iidx=0;iidx!=g.getGraphVertexNumber();++iidx)
                                        {
                                                if(1==g.getGraphEdgeWeight(rootNode.front(),iidx)&&
                                                        false==visited[iidx])
                                                {
                                                        cout<<g.getGraphVertexData(iidx)<<" ";
                                                        visited[iidx] = true;
                                                        rootNode.push(iidx);
                                                }
                                        }
                                        rootNode.pop();  //最先访问的一个结点出队列
                                }
                        }
                }
        }
};

两种遍历算法在时间复杂度上是一样的
深度优先遍历算法适合图和边都非常多,要找到合适的顶点
广度优先遍历算法适合不断扩大遍历范围时找到相对最优

图的深度优先遍历(DFS)和广度优先遍历(BFS)的更多相关文章

  1. 图的深度优先搜索(DFS)和广度优先搜索(BFS)算法

    深度优先(DFS) 深度优先遍历,从初始访问结点出发,我们知道初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接 ...

  2. 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)

    深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...

  3. 深度优先搜索DFS和广度优先搜索BFS简单解析

    转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...

  4. 图的 储存 深度优先(DFS)广度优先(BFS)遍历

    图遍历的概念: 从图中某顶点出发访遍图中每个顶点,且每个顶点仅访问一次,此过程称为图的遍历(Traversing Graph).图的遍历算法是求解图的连通性问题.拓扑排序和求关键路径等算法的基础.图的 ...

  5. 图的深度优先遍历(DFS)和广度优先遍历(BFS)算法分析

    1. 深度优先遍历 深度优先遍历(Depth First Search)的主要思想是: 1.首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点: 2.当没有未访问过的顶点时,则回 ...

  6. 深度优先搜索DFS和广度优先搜索BFS

    DFS简介 深度优先搜索,一般会设置一个数组visited记录每个顶点的访问状态,初始状态图中所有顶点均未被访问,从某个未被访问过的顶点开始按照某个原则一直往深处访问,访问的过程中随时更新数组visi ...

  7. 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)

    图的遍历的定义: 从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次.(连通图与非连通图) 深度优先遍历(DFS): 1.访问指定的起始顶点: 2.若当前访问的顶点的邻接顶点有未被访问的,则 ...

  8. 【C++】基于邻接矩阵的图的深度优先遍历(DFS)和广度优先遍历(BFS)

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

  9. 图的深度优先搜索dfs

    图的深度优先搜索: 1.将最初访问的顶点压入栈: 2.只要栈中仍有顶点,就循环进行下述操作: (1)访问栈顶部的顶点u: (2)从当前访问的顶点u 移动至顶点v 时,将v 压入栈.如果当前顶点u 不存 ...

随机推荐

  1. sublime Text如何取消两栏窗口?

    在菜单栏里的 View->LayOut->Single,也可以用快捷键 Alt+Shift+1.如图所示.(亲测可用) &amp;lt;img src="https:// ...

  2. SQLSERVER 和 ORACLE的if not exist 用法

    sql server: if not exists (select 1 from TB_Procedure where Id='2018ZZZ') BEGIN insert into TB_Proce ...

  3. java8新特性(二)_lambda表达式

    最近一直找java8相关新特性的文章,发现都太没有一个连贯性,毕竟大家写博客肯定都有自己的侧重点,这里找到一本书,专门介绍java8新特性的,感觉大家可以看看<写给大忙人看的JavaSE8> ...

  4. MySQL中如何实现select top n ----Limit

    Mysql中limit的用法详解 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. LIMIT 子句可以被用于强制 S ...

  5. English trip M1 - PC7 Can I Borrow Your Ping-Pong? Teacher:Patrick

    In this lesson you will learn to desribe abilities.  这节课你将学习到描述你的能力 课上内容(Lesson) 三种常见情态动词 can aux. 能 ...

  6. 请问WCF 跟 WebService之间的相同跟异同

    https://social.msdn.microsoft.com/Forums/zh-CN/c06420d1-69ba-4aa6-abe5-242e3213b68f/wcf-webservice W ...

  7. JDK常用工具

    JDK的命令行工具 jps 查看正在使用的jvm机器进程号. 常用命令,-l显示正在运行的jar包或者软件(基于jvm),-v显示当前进程详细的jvm参数 jps -l jps -v javap 反汇 ...

  8. python记录_day09 初识函数

    一.认识函数 函数:对动作或者功能的封装 格式: 函数声明     def  函数名(): 函数体 函数调用     函数名() #定义函数 def xiao(): print("你的笑像一 ...

  9. PTA L2-002 链表去重

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805072641245184 第一次做链表题,有时间多看看 解释 ...

  10. svn: 提交终止

    今天我遇到了svn 的问题  svn: 提交终止: “/var/www/modelfinance/modules/incomereport/views/purchase” 处于冲突状态 冲突状态搞的我 ...