目录点这里:【数据结构与算法】相关文章目录
DFS (Deep First Search)
概念:
顾名思义,这种遍历方法是以深度优先来遍历图,大致意思是如果这条路还能走,就一直走到底。具体解释如下:
例:下图中,start为搜索的初始节点,end为目标节点
深度优先的[递归]伪代码如下:
void find(节点){
if(此结点已经遍历 || 此节点在图外 || 节点不满足要求) return;
if(找到了end节点) 输出结果 ; return;
标记此节点,表示已经遍历过了;
while(存在下一个相关联的节点) find(下一个节点);
}
find(start节点);
a.可以看出,若没有走到死路,这种遍历方式会沿着一条路一直深入下去。
b.若走到死路,便会退回上一节点,遍历上一节点的其他相关联的节点。
c.这样一直重复,直到找到终点。
所以把这种遍历方法命名为深度优先算法是很直观的,这种方法也一般用来寻找迷宫的出路,或者求连通块的数量。
应用例题:油田(Oil Deposits, UVa 572)
BFS (Breadth First Search)
概念:
根据深度优先算法联想一下,广度优先应该是把当前每一种可能的下一步全走完,而不是一条路走到死。具体解释如下:
例:下图中,start为搜索的初始节点,end为目标节点
a.第一步,我们先把star节点的关联节点遍历一次
b.接下来把第一步遍历过的节点当成start,重复第一步
c.这是一个放射形的搜索方式,重复一二步,直到找到end
可以看出,这样放射性的寻找方式,能找到从start到end的最近路(因为每次只走一步,且把所有的可能都走了,谁先到end说
明这就是最短路)。但这样如何用代码实现?用栈貌似不行,改变递归的顺序也不行。
这里需要用到队列:
a.比如每遍历start周围的一个“1”节点的时候,就把跟它相关联的“2”节点保存到队列中(“1”节点访问完之后队列内容:2,2,2,2)
b.然后依次访问队列内容,并对每个队列元素重复a步骤(访问一个“2”节点之后队列的内容:2,2,2,3,3)。
c.由此重复下去,直到队列为空或者搜索到终点。
广度优先的[递归]伪代码如下:
把start节点push入队列;
while(队列不为空) {
把队列首节点pop出队列;
对节点进行相关处理或者判断;
while(此节点有下一个相关节点){
把相关节点push入对列;
}
}
应用例题:Abbott的复仇(Abbott's Revenge, ACM/ICPC World Finals 2000, UVa 816)