1. 程式人生 > >深度優先搜尋與全排列

深度優先搜尋與全排列

      做題過程中我們經常會遇到這樣的問題:

輸入一個數n,輸出1-n的全排列。可能很多人會想到列舉暴力,這裡給大家介紹一種演算法:深度優先搜尋

在這裡舉個簡單的例子  

      假如有編號為1 、2、3 的3 張撲克牌和編號為l 、2 、3 的3 個盒子。
現在需要將這3 張撲克牌分別放到3 個盒子裡面,並且每個盒子有且只能放一張撲克牌。那麼一共有多少種不同的放法呢?

   首先 我們應該設定一個標誌陣列 book 記錄當前數字是否被使用過。

   然後用一個數組a 表示盒子並且初始化a[i]=i;

  程式碼如下:

#include<stdio.h>
int n,a[10],book[10];//特別說明c語言全域性變數沒有賦值預設為 0,無需再次初始化; 
void dfs(int step)//step 表示當前在第幾個位置 
{
	int i;
	if(step==n+1)//如果step==n+1表示前n個數字已經放好 
	{
		//輸出一種全排列 
		for(i=1;i<=n;i++)
		 printf("%d",a[i]);
	    printf("\n");
	   return; 
	}
	//每次搜尋都從1-n 一一嘗試 
	for(i=1;i<=n;i++)
	{
		if(book[i]==0)//判斷次數字是否用過 
		{
			a[step]=i;//儲存當前位置的數字,以便滿足條件輸出 
			book[i]=1;//當前數字已用過,改變標誌,以防重用 
			dfs(step+1);//放好當前位置數字之後,安排下一個數字 
			book[i]=0;//回溯,當滿足一種全排列後,進行下一種嘗試 
		}
	}
	return ;
}
int main()
{
	scanf("%d",&n);//輸入只能為1-9之間的整數,表示1-n的全排列 
	dfs(1);//從第一個位置開始 
	return 0;
} 

同時總結了下基本模型,希望有用:
void dfs(int step)
{
     判斷邊界
      嘗試每一種可能
      for(i=1;i<=n;i++)
     {
             繼續下一步dfs(step+1);
     }
   返回
}