深度优先跟广度优先
Posted 功夫熊猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度优先跟广度优先相关的知识,希望对你有一定的参考价值。
深度优先的模型,像是一条道走到黑,不撞南墙不回头的模式。但是基于的模型,类似于堆栈模型。再撞到南墙的时候,回溯到上一次撞墙前的位置。这样的的操作相当于stack的pop出最新入栈的那条数据。然后继续找一个之前没有走过的结点尝试。
这样一来在脑子里会有一个stack模型,记录从根节点走到当前结点位置的栈。便于撞到南墙之后的回溯。另外一个数组用标记已经访问过的结点,且在装完南墙之后的路径上。
整个算法过程:
当前结点i,查找跟结点i的子节点j,同时判断book[j]是否被标记。如果没有标记则book[j]不存在,则j入栈Stack。如果book[j],已经存在,且i没有没有访问过的子节点,则Pop[i];回到i的父节点,重复上面的过程。直到遍历完所有的结点,或者找到目标结点退出。
php代码:
假设是一颗完全的二叉树结构,用数组模式存储
1
/ \
2 3
/ \ /
4 5 6
用数组保存这棵树就是arr[1,2,3,4,5,6];这个只是下标,里面可以存值。为了更直观的表示,所以key默认是值。
dfs($i)
{
$l = $arr[$i*2];//左孩子
$r =$arr[$i+1];//右孩子
if(isset($l) && $book[$l] == '')
{
//这个表名左孩子存在且没有被访问过
$book[$l] = 1;
$i = $l;
array_push($stack,$l);
dfs($l);//将当前结点入栈,同时递归调用本身
}
if(isset($r) && $book[$r] == '')
{
$book[$r] = 1;
$i = $r;
array_push($stack;$l);
dfs($i);
}
while($j = array_pop($stack))
{
dfs($j);
}
}
一般应用的话,应该是寻找某个结点,所以只需要在里面的加上是否相等的判断,在每次寻找路径的过程中,加上判断与要查找的key是否相等,就可以退出找到。若是循环完都没有return key就是没有要查找的值。
广度优先搜索,是基于不断扩大的过程。直到遍历完所有的结点或者找到要查找的值key。这个模型类似于队列。先进先出的队列模型。依次拓展存在的队列不断扩大搜索成果。
同样以完全二叉树为例,比较形象方面理解。
1
/ \
2 3
/ \ /
4 5 6
初始化的队列$arr[1]只有根节点,从根节点开始遍历
依次遍历后$arr[2,3];
然后将1出队列,2变成队首,开始递归第一步操作查找2为根节点的子节点。
结果变成[3,4,5];
将2出列,3变成队首,开始递归第一步操作。
结果变成[4,5,6];
php代码:
bfs($i)
{
$l = 2*$i ;//左孩子
$r = 2*$i + 1;
if(isset($l))
{
array_push($queen;$l);
}
if($r)
{
array_push($queen,$r);
}
while($head = array_shift($arr))
{
bfs($head);
}
return $arr;
}
这个是超级简化后的抽象广度优先,跟深度优先搜索。反正原理如此,实际问题还是实际分析。而且实际问题也比这个模型复杂, 但是基本的原理就是这样。
以上是关于深度优先跟广度优先的主要内容,如果未能解决你的问题,请参考以下文章
数据结构与算法图遍历算法 ( 深度优先搜索 DFS | 深度优先搜索和广度优先搜索 | 深度优先搜索基本思想 | 深度优先搜索算法步骤 | 深度优先搜索理论示例 )