对深度优先搜索(DFS)的理解
请结合具体例子看 必要时将每一步具体数据写下
注明: 代码里数据有两个主要类型,
一个是位置pos数组,相当于n个盒子。相关的是step,是位置的移动。
一个是要排列的n个数字 i(1-n)。相关的是 i 的标记tick,是针对数字而不是位置的。
/*全排列(用DFS)*/ #include<stdio.h> int n;//要全排列的n个数(1-n) int pos[1000];//有n个数 对应n个位置(是位置不是那n个数,数是要按一定顺序填到这些空里的) int tick[1000];//n个数,每个数都有标记 tick[]对应每个数在该次排列里有无用到 void DFS(int step) { int i; /*每次dfs递归 首先做一次判断*/ /*递归停止的依据是位置n个数都排到n个位上*/ if(step==n) { /*一次全排列后 需做的处理*/ for(i=0; i<n; i++) { printf("%d ", pos[i]); } printf("\n"); } /*n个位没排完 重要处理*/ else { for(i=1; i<=n; i++)//循环n次 看1-n有没有没被标记的数;递归返回时,i全过一遍完后,也要向上返回 { if(tick[i]==0)//找到没被标记的数,深度向下试探。试完后,这一层看i+1有没有标记,相同操作,以此类推 { pos[step]=i;//把没标记过(没用过)的i放入当前位置step tick[i]=1; //i用了,将i标记 DFS(step+1);//安排下个位置(FDS递归 进入下一层) tick[i]=0;//释放标记都是在一次完整的全排列完成后做的,从最后排的位置开始释放这位子的数, //该位置前一个位置就能取用被释放标记的数(因为递归回去,这个节点继续for循环) //或者后面一排的循环到头 回上一位置 就要把上一位置的数的标记清零 } } } return; } int main() { scanf("%d", &n); DFS(0);//这里排位子从第0位开始 return 0; }

浙公网安备 33010602011771号