BFS(广搜):

广搜就是广度优先搜索,根据名字可以知道,是通过广度来遍历图,也就是层次遍历吧。

在这里以及下面的DFS(深搜),都用到了颜色WHITE,GRAY,BLACK,不过作用不同,具体分别再分析。

在BFS中,WHITE,GRAY,BLACK这三色是用来记录一个点是否被搜到,以及是否它的邻接点都是灰色。(具体见P324倒数第2段)。

P326 的图22-3是个经典的图,看了此图基本就知道BFS是干嘛的了。

在图22-3中,因为他是用字母表示的,我把各点定义为顺时针从标号1开始,于是r点是1号,源点s是2号。

这是我写的具体实现(C/C++):

/*
* Introduction to Algorithms
* Chapter 22 --- BFS
* Tanky Woo @ www.WuTianQi.com
* 2012.1.6
*/
#include
#include
#define WHITE 0
#define GRAY 1
#define BLACK 2
#define MAX 999999
#define NIL 0 using namespace std; int node;
int G[100][100];
int color[100];
int dist[100];
int prev[100]; void BFS(int source)
{
for(int i=1; i<=node; ++i)
{
color[i] = WHITE;
dist[i] = MAX;
prev[i] = NIL;
}
color = GRAY;
dist = 0;
prev = NIL; queue que;
que.push(source); while(!que.empty())
{
int no = que.front();
que.pop();
for(int i=1; i<=node; ++i)
if(G[no][i]==1 && color[i]==WHITE)
{
color[i] = GRAY;
dist[i] = dist[no] + 1;
prev[i] = no;
que.push(i);
}
color[no] = BLACK;
} } void printPath(int source, int dest)
{
if(source == dest)
cout << source;
else if(prev[dest] == NIL)
cout << "No path from " << source << " to " << dest << " exist\n";
else
{
printPath(source, prev[dest]);
cout << " " << dest;
} } int main()
{
freopen("input.txt", "r", stdin); memset(G, 0, sizeof(G));
cout << "Input the number of the node:\n";
cin >> node;
cout << "Input the Graph:\n";
for(int i=1; i<=node; ++i)
for(int j=1; j<=node; ++j)
cin >> G[i][j];
BFS(2); cout << dist[4] << endl;
cout << "The path: ";
printPath(2, 4); }

这是input.txt的内容:

8
0 1 0 0 0 0 0 1
1 0 0 0 0 0 1 0
0 0 0 1 0 1 1 0
0 0 1 0 1 1 0 0
0 0 0 1 0 1 1 0
0 0 1 1 1 0 0 0
0 1 1 0 1 0 0 0
1 0 0 0 0 0 0 0

可以看到结果,源点(2号)到u点(4号)的距离是3.

源码我上传到我的网盘了:

http://www.kuaipan.cn/file/id_35241628297855049.html

DFS(深搜):

深搜既深度优先搜索,相对于BFS,它是尽可能深的去搜索一个图。

在DFS中,仍然用到了WHITE, GRAY,BLACK,但是它们的用处和BFS有些不同,这里他们是用来表示时间戳,因为DFS会有回溯,所以也就有第一次和第二次搜到。(具体见P330面)

看P331面图22-4。

具体实现(C/C++):

/*
* Introduction to Algorithms
* Chapter 22 --- DFS
* Tanky Woo @ www.WuTianQi.com
* 2012.1.6
*/ #include
#include
#define WHITE 0
#define GRAY 1
#define BLACK 2
#define NIL 0 using namespace std; int node;
int G[100][100];
int color[100];
int fir[100], sec[100]; // 用来记录前后时间戳
int prev[100];
int time; // time用来记录时间戳 void DFS_VISIT(int no)
{
color[no] = GRAY; // 当点no第一次被搜到
++time;
fir[no] = time;
for(int i=1; i<=node; ++i)
{
if(G[no][i]==1 && color[i]==WHITE)
{
prev[i] = no;
DFS_VISIT(i);
}
}
color[no] = BLACK; // 当点no深搜完回溯时再次搜到
sec[no] = ++time; } void DFS()
{
for(int i=1; i<=node; ++i)
{
if(color[i] == WHITE)
prev[i] = NIL;
}
time = 0;
for(int i=1; i<=node; ++i)
{
if(color[i] == WHITE)
DFS_VISIT(i);
}
} int main()
{
freopen("input.txt", "r", stdin); memset(G, 0, sizeof(G));
cout << "Input the number of the node:\n";
cin >> node;
cout << "Input the Graph:\n";
for(int i=1; i<=node; ++i)
for(int j=1; j<=node; ++j)
cin >> G[i][j]; DFS();
cout << "点v(2号)的first:" << fir[2] << " 和second:" << sec[2] << endl;
}

这是input.txt的内容:

6
0 1 0 0 0 1
0 0 0 0 1 0
0 0 0 1 1 0
0 0 0 1 0 0
0 0 0 0 0 1
0 1 0 0 0 0

可以看到结果,点v(2号)的first和second分别是2和7

源码我上传到我的网盘了:

http://www.kuaipan.cn/file/id_35241628297855052.html

(拓扑排序下次再写吧)

小结:

DFS和BFS是图算法的根本,但是刚开始了解可能不太习惯,建议找一些相应的题目来试试手。可以在我Blog搜BFS和DFS,可以找到我曾经做过的题目。

《算法导论》学习总结 — XX.第22章 图的基本算法的更多相关文章

  1. (搬运)《算法导论》习题解答 Chapter 22.1-1(入度和出度)

    (搬运)<算法导论>习题解答 Chapter 22.1-1(入度和出度) 思路:遍历邻接列表即可; 伪代码: for u 属于 Vertex for v属于 Adj[u] outdegre ...

  2. 算法导论学习---红黑树具体解释之插入(C语言实现)

    前面我们学习二叉搜索树的时候发如今一些情况下其高度不是非常均匀,甚至有时候会退化成一条长链,所以我们引用一些"平衡"的二叉搜索树.红黑树就是一种"平衡"的二叉搜 ...

  3. 《算法导论》学习总结 — XX.第23章 最小生成树

    一.什么叫最小生成树 一个无向连通图G=(V,E),最小生成树就是联结所有顶点的边的权值和最小时的子图T,此时T无回路且连接所有的顶点,所以它必须是棵树. 二.为什么要研究最小生成树问题 <算法 ...

  4. 算法导论学习-Dynamic Programming

    转载自:http://blog.csdn.net/speedme/article/details/24231197 1. 什么是动态规划 ------------------------------- ...

  5. 算法导论学习之线性时间求第k小元素+堆思想求前k大元素

    对于曾经,假设要我求第k小元素.或者是求前k大元素,我可能会将元素先排序,然后就直接求出来了,可是如今有了更好的思路. 一.线性时间内求第k小元素 这个算法又是一个基于分治思想的算法. 其详细的分治思 ...

  6. 《算法导论》习题解答 Chapter 22.1-5(求平方图)

    一.邻接矩阵实现 思路:如果是邻接矩阵存储,设邻接矩阵为A,则A*A即为平方图,只需要矩阵相乘即可: 伪代码: for i=1 to n for j=1 to n for k=1 to n resul ...

  7. 算法导论学习-RED-BLACK TREE

    1. 红黑树(RED-BLACK TREE)引言: ------------------------------------- 红黑树(RBT)可以说是binary-search tree的非严格的平 ...

  8. 《算法导论》习题解答 Chapter 22.1-8(变换邻接表的数据结构)

    一般散列表都与B+树进行比较,包括在信息检索中也是. 确定某条边是否存在需要O(1). 不足: (1)散列冲突. (2)哈希函数需要不断变化以适应需求. 另外:B+树.(见第18章) 与散列表相比的不 ...

  9. 《算法导论》习题解答 Chapter 22.1-6(求universal sink 通用汇点)

    思路:设置两个游标i指向行,j指向列,如果arr[i][j]==1,则i=max{i+1,j},j++:如果arr[i][j]==0,则j=max{i+1,j+1}. 伪代码: has_univers ...

随机推荐

  1. 设置Linux环境变量的方法与区别(Ubuntu)

      设置 Linux 环境变量可以通过 export 实现,也可以通过修改几个文件来实现,有必要弄清楚这两种方法以及这几个文件的区别.   通过文件设置 Linux 环境变量 首先是设置全局环境变量, ...

  2. SSL证书:Web加密使互联网更安全

    在网络安全的圈子里,我们都会隔三差五的听到某某公司遭受恶意软件攻击.或大量的隐私信息被泄露等等事件,此类安全事件往往都有影响范围广.涉及用户众多等特点.不免让人质疑联网的世界越来越危险.然而,在安全专 ...

  3. vue2+swiper(用户操作swiper后,不能autoplay了)

    将autoplayDisableOnInteraction设置为false

  4. 探索 ConcurrentHashMap 高并发性的实现机制

    很不错的一篇文章,值得一看 http://www.ibm.com/developerworks/cn/java/java-lo-concurrenthashmap/

  5. WCF(三)分布式事务

    最近在学WCF,所以有两个设想疑问(菜鸟多疑问): 如果有WCF服务A,WCF服务B,客户端调用WCF服务A插入一条数据,然后再调用服务B也插入一条数据,然而服务B出错了进行了回滚,服务A能不能也进行 ...

  6. angularJS+Ionic移动端图片上传的解决办法

    前端开发中经常会碰到图片上传的问题,网上的解决办法很多,可是有些图片上传的插件会有一些附属的插件,因此因为一个图片上传的问题可能额需要引入其他插件到项目中,久而久之项目会不伦不类,有时候插件之间也会有 ...

  7. SQL Server 2008 开启数据库的远程连接

     转载: 陈萌_1016----有道云笔记 SQL Server 2008默认是不允许远程连接的,如果想要在本地用SSMS连接远程服务器上的SQL Server 2008,远程连接数据库.需要做两个部 ...

  8. ant安装以及环境变量配置、验证

    (一)安装 ant 下载地址: http://ant.apache.org/     根据自己电脑下载对应版本 下载完成以后,可自行解压到自己常用的盘中,但是要记住解压到哪里了,以便后续的环境变量配置 ...

  9. CentOS6.5下LNMP环境的搭建

    #写的不好,大牛勿喷 #其实我很努力 OS:CentOS6.5 1.关闭SELinux,关闭防火墙 原因:1.SELinux确实可以提高服务器的安全性,但是对于服务器的性能存在一定的影响,同时它的复杂 ...

  10. 201521123084 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...