把数字当做扑克牌按照一定顺序依次放到盒子内。
public class DfsTest {
//深度优先遍历, 求从1到n的所有数字排列
static int a [] = new int[10];
static int book [] = new int[10];//book中的值为标记用,初始值设置为0,为扑克牌在手上时
static int n = 3;//几个数字的全排列n
static int sum = 0;
static {
//为a和book数组赋值
for (int j = 1; j <= n; j ++){
a[j] = j;
book[j] = 0;
}
}
public static void main(String[] args) {
DfsTest test = new DfsTest();
test.dfs(1);
}
public void dfs(int step){//step 为目前站在第几个盒子面前
System.out.println(step+","+n);
int i;
if(step == n + 1){//如果站在n+1盒前,表示前n个盒子已经放好
for (i = 1; i <= n; i ++){
System.out.print(a[i]);
}
sum++;
System.out.println("here"+sum);
return;
}
//此时站在第step个盒子面前,应该放哪张牌呢?
//按照1,2,3,,,n的顺序一一尝试
for (i = 1; i <= n; i ++){
//判断扑克牌是否在手
if(book[i] == 0){// 0 表示在手
//开始尝试使用扑克牌
a[step] = i;//将i号放入第step个盒子中
book[i] = 1;// 1 表示不在手
//第step个盒子已放好扑克,接下来就走到下一个盒子面前
dfs(step + 1); //递归
book[i] = 0; // 最重要的,,尝试过的扑克收回,才可进行下一次
}
}
return;
}
}
理解深度优先搜索的关键在于“当下该如何做”,至于“下一步如何做”和“当下如何做”是一样的。比如这里写的dfs(step)函数的主要功能就是解决当你在第step个盒子的时候该怎么办,通常的方法就是把每种可能都试一遍(for循环遍历),当前这一步解决后便进入下一步dfs(step+1)。下一步的解决方法和当前这步的解决方法是完全一样的。
void dfs(int step){
判断边界
//尝试每种可能
for(i = 1; i <= n; i ++){
//继续下一步
dfs(step+1);
}
返回
}
本文借鉴来自《啊哈!算法》,感谢作者啊哈磊的生动讲解!