019-dfs.bfs-图的遍历-《算法设计技巧与分析》M.H.A学习笔记

Posted luciozhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了019-dfs.bfs-图的遍历-《算法设计技巧与分析》M.H.A学习笔记相关的知识,希望对你有一定的参考价值。

深度优先搜索DFS

深搜框架:

bool dfs(int loc) {
    标记状态loc已访问;
    if (loc为目标状态) return true;
    for (每个可能的操作) {
         对loc应用操作产生新状态nstat;
         if (nstat合法且未被访问) {
		if (dfs(nstat)) return true;
         }
    }
    撤销loc已访问标记; // 这步要具体问题具体分析了
    return false;
}


广度优先搜索BFS

实现方法

1. 首先将根节点放入队列中。

2. 从队列中取出第一个节点,并检验它是否为目标。

· 如果找到目标,则结束搜寻并回传结果。

· 否则将它所有尚未检验过的直接子节点加入队列中。

3. 若队列为空,表示整张图都检查过了——亦即图中没有欲搜寻的目标。结束搜寻并回传找不到目标

4. 重复步骤2

广搜框架:

<pre name="code" class="cpp">bool bfs(int init) {
    que.enque(init);
    while (队列que不是空的) {
          	int loc = que.front();   que.deque();
          if (loc是目标状态) return true;
          for (每个可能的操作) {
                对loc应用操作产生新状态nstat;
                if (nstat合法且未入队) {
		标记nstat已入队;
		que.enque(nstat);
	      }
          }
    }
return false;
}



补充:

简化代码:

在一类搜棋盘、搜地图、搜矩阵位置的问题中我们会频繁遇到“从当前点获取相邻点”的操作,为了缩短代码,我们可以开个方向数组dir[][2]表示方向,以4方向为例,则dir[4][2] = {{0, 1}, {1, 0}, {0, 1}, {-1, 0}};

用的时候有:

for (int i = 0; i < 4; ++i) 
{
	int newX = oldX + dir[i][0];
	int newY = oldY + dir[i][1];
	if (newX,newY均合法且未访问) // bfs或dfs的相关操作
}

记录路径:

广搜:

如果题目需要我们记录解路径,则对于广搜有:

struct TStat{
	int value;
	int pre;	// 记录其父状态在队列中的位置,初始化为-1;
};

每次扩展新状态的时候令新状态的pre为当前状态在队列中的下标,待到达目标状态之后倒着查回第一个状态即可获取解路径。

深搜:

对于深搜,则可另外开一个栈用来记录当前的合法状态,每次访问新状态前都压入当前状态到栈中,回溯时也相应地弹出栈顶,最终这个栈里将逆序记录解路径上的节点。大致做法如下:

stack<int> stk;
bool dfs(int loc) {
    标记状态loc已访问;
    stk.push(loc);
    for (每个可能的操作) {
         对loc应用操作产生新状态nstat;
         if (nstat合法且未访问) {
	if (dfs(nstat)) return true;
         }
    }
    stk.pop();
    撤销loc已访问标记;
    return false;
}

以上是关于019-dfs.bfs-图的遍历-《算法设计技巧与分析》M.H.A学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

数据结构C语言版 图的遍历 DFS和BFS算法,用邻接矩阵储存 急阿在线等 求大神指点

20162308 2017-2018-2 《程序设计与数据结构》第11周学习总结

数据结构与算法10—图的遍历

数据结构与算法-图的遍历

数据结构与算法: 三十张图弄懂「图的两种遍历方式」

GIS算法原理与开发2021-深度优先遍历