参考http://chen-tao.github.io/2017/01/25/about-bfs/
- BFS
常用于计算图的连通性,单源最短路径,计算最小操作次数
···
public class GraphNode{
int val;
List neighbors;
}
public void BFS(GraphNode start){
LinkedList q = new LinkedList();
HasheSet visited = new HasheSet();
q.push(start);
visited.add(start);
while(!q.empty()){
GraphNode cur = q.poll();
System.out.println(cur.val);
for(GraphNode next: cur.children){
if(!visited.contains(next)){
q.push(next);
visited.add(next); // mark node as visited when adding to queue!
}
}
}//while
}
··· - DFS
使用一个hashset来保存已经遍历过的节点
HashSet<GraphNode> visited = new HashSet<GraphNode>();
//递归版本
public void DFS(GraphNode nd){
//print nd.val
visited.add(nd);
for(GraphNode next : nd.neighbours){
if(!visited.contains(next)){
DFS(next);
}
}
}
//非递归版本
public void DFS(GraphNode start){
Stack<GraphNode> s = new Stack<GraphNode>();
q.push(start);
visited.add(start);
while(!s.empty()){
GraphNode cur = s.pop();
//print cur.val
for(GraphNode next : cur.children){
if(!visited.contains(next)){
s.push(next);
visited.add(next);//mark node as visited when adding to stack.
}
}
}//while end
}
//回环检测
public void DFS(GraphNode nd){
visited.put(nd, false); // mark as status-1
for(GraphNode next: nd.neighbors){
if( !visited.contains(next) )
DFS(next);
else if(visited.get(next)==false) // found cycle
System.out.println("Cycle detected!!!");
}// now all touchable nodes from nd are visited
visited.put(nd, true); // mark as status-2
}
- 递归
一般结构
void f()
{
if(符合边界条件)
{
///
return;
}
//某种形式的调用
f();
}
- 回溯
DFS适用于 显式图,但是对于一些隐式关系,我们需要使用回溯法,通过定义或找到各个状态、边界条件、搜索范围、约束条件和最优解结果进行建模求解。
边界条件:达到某状态时,需要检查并确定是继续搜索还是回到上一状态的条件(例如当前已使用时间比当前最优解要长,此时就不需要再进行搜索)
搜索范围:当前从当前状态开始进行搜索的所有下一级状态。
搜索范围:
另外一定要注意,假如参与递归的参数不是通过传参形式的方式进入递归的话,那么一定要做好数据恢复。
//一般结构
void dfs(int 当前状态)
{
if(当前状态为边界状态)
{
记录或输出
return;
}
for(i=0;i<n;i++) //横向遍历解答树所有子节点
{
//扩展出一个子状态。
修改了全局变量
if(子状态满足约束条件)
{
dfs(子状态)
}
恢复全局变量//回溯部分
}
}