深度优先算法
基本思想
从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念。
为了实现深度优先搜索,首先选择一个起始顶点并需要遵守三个规则:
- 如果可能,访问一个邻接的未访问顶点,标记它,并把它放入栈中。
- 当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点。
- 如果不能执行规则1和规则2,就完成了整个搜索过程。
基本模型(参考《啊哈算法》,通过递归完成)
void dfs(int step){ 判断边界 尝试每一种可能 for(i=0;i<n;i++){ 继续下一步 dfs(step+1); } 返回 }
算法关键在于解决“当前该怎么做”,以后的步骤应该和当前一致,通常通过for循环遍历将每种可能都尝试一遍,解决这一步之后变递归进入下一步。
简单栗子(实现多个数的全排列)
public class Dfs { public static int nums[]={5,7,9,2}; public static int box[]={0,0,0,0}; public static boolean book[]={true,true,true,true}; public static void main(String[] args) { dfs(0); } public static void dfs(int step){ //当达到边界条件后返回 if(step>=box.length){ for(int i=0;i<box.length;i++){ System.out.print(box[i]+"\t"); } System.out.println(); return ; } //循环当前的所有可能 for(int i=0;i<nums.length;i++){ if(book[i]){ box[step]=nums[i]; book[i]=false; dfs(step+1); book[i]=true; } } } }
上面代码中的nums代表需要被排列的数字集合,box代表用来放数字的容器。(相当于将四个数字分别放在四个盒子中共有多少种情况。),book用来标记nums数组中的已经被放入盒子中的数字。