对深度优先搜索(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;
} 

 

posted @ 2017-03-11 10:15  MetalTree  阅读(1367)  评论(0)    收藏  举报