深度優先搜尋與全排列
阿新 • • 發佈:2018-12-24
做題過程中我們經常會遇到這樣的問題:
輸入一個數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);
}
返回
}