国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#深度優先遍歷實現全排列

2020-01-23 20:46:12
字體:
來源:轉載
供稿:網友

假如讓你說出123三個數字的全排列你可以很快說出來123,132,213,231,312,321,但是讓你說出1~20總共20個數字的全排列是不是就沒那么簡單了呢?本篇我們就通過C#運用深度優先算法實現全排列

算法圖例

假如有編號為1,2,3的三張撲克牌和編號為1,2,3的三個盒子,現在需要將三張撲克牌分別放到三個盒子中。

我們把這個問題轉化為一個最基本的問題:如何往小盒子中放撲克牌。每個小盒子都可能放1,2,3號撲克牌,這需要一一嘗試,就需要一個for循環來解決。

  for (int i = 1; i < = n; i++)  {    a[step] =i; //將i號撲克牌放入第step個盒子中  }

數字a用來記錄每個盒子放的哪張牌,step表示當前是第幾個盒子,a[step] =i就是將i號撲克牌放入第step個盒子中。此時有一個問題就是一張牌已經放在第step個盒子中了就不能再放到其它盒子里了,因此還需要一個數組book來標記哪些牌已經使用了。

      for (int i = 1; i < = n; i++)      {        if(book[i]==0) //book[i]==0表示第i號牌仍然在手中        {          a[step] =i; //將i號撲克牌放入第step個盒子中          book[i] =1; //設為1,表示第i號牌已經不在手中        }              }

現在第step個盒子中的牌已經放好了,接下來需要看下一個盒子step+1中放什么牌,處理方法和上一個盒子是一樣的,這里我們可以把上一步的步驟封裝成一個函數dfs,下一步繼續調用,如下:

void dfs(int step) {       for (int i = 1; i < = n; i++)      {        if(book[i]==0) //book[i]==0表示第i號牌仍然在手中        {          a[step] =i; //將i號撲克牌放入第step個盒子中          book[i] =1; //設為1,表示第i號牌已經不在手中        }              }    }

然后我們在處理step+1的時候就可以直接調用dfs函數了,如下:(注意標注重點的代碼)

    void dfs(int step) {       for (int i = 1; i < = n; i++)      {        if(book[i]==0) //book[i]==0表示第i號牌仍然在手中        {          a[step] =i; //將i號撲克牌放入第step個盒子中          book[i] =1; //設為1,表示第i號牌已經不在手中          dfs(step+1);//(重點)處理下一步放什么牌          book[i] =0; //(重點)在嘗試完一輪之后,需要將牌都收回才能進行下一輪的嘗試        }              }    }

上面代碼中的book[i] =0;非常重要,這句的作用是將盒子中的撲克牌收回,因為在一次擺放完成結束時,如果不把盒子中的牌收回將無法進行下一次擺放。還剩下一個問題,就是什么時候輸出一個滿足要求的序列呢?其實當我們處理第n+1個盒子的時候(即step=n+1)就代表前面n個盒子已經放好了,這個時候a數組中的撲克牌序列就是滿足條件的結果,將a數組中的元素按順序打印即可。注意!打印完需要執行return,不然程序還會繼續往下執行。

    void dfs(int step) {       if (step==n+1) //如果到了第n+1個盒子,說明前面n個盒子都已經放好     {     //輸出一種結果        for (int i = 0; i < a.length; i++)    {      Console.Write(a[i]);    }        return; //返回到最近一次調用dfs函數的地方     }      for (int i = 1; i < = n; i++)      {        if(book[i]==0) //book[i]==0表示第i號牌仍然在手中        {          a[step] =i; //將i號撲克牌放入第step個盒子中          book[i] =1; //設為1,表示第i號牌已經不在手中          dfs(step+1);//處理下一步放什么牌          book[i] =0; //在嘗試完一輪之后,需要將牌都收回才能進行下一輪的嘗試        }              }    }

好了,以上就是完整思路,下面我們看下完整代碼及調用過程:

  class Program  {    static int n = 0;    static int[] a;    static int[] book;    static void Main(string[] args)    {      Console.WriteLine("請輸入數字N:");      n = int.Parse(Console.ReadLine());      Console.WriteLine("數字1~"+n+"的全排列為:");      a = new int[n+1];      book = new int[n+1];      dfs(1);      Console.ReadLine();    }    static void dfs(int step)    {      if (step == n + 1) //如果到了第n+1個盒子,說明前面n個盒子都已經放好      {        //輸出一種結果        for (int i = 1; i < a.Length; i++)        {          Console.Write(a[i]);        }        Console.WriteLine();        return; //返回到最近一次調用dfs函數的地方      }      for (int i = 1; i <= n; i++)      {        if (book[i] == 0) //book[i]==0表示第i號牌仍然在手中        {          a[step] = i; //將i號撲克牌放入第step個盒子中          book[i] = 1; //設為1,表示第i號牌已經不在手中          dfs(step + 1);//處理下一步放什么牌          book[i] = 0; //在嘗試完一輪之后,需要將牌都收回才能進行下一輪的嘗試        }      }    }  }

看下運行結果:

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 咸阳市| 固原市| 阳城县| 黎平县| 沙洋县| 驻马店市| 揭西县| 那坡县| 闸北区| 化隆| 玉田县| 钟祥市| 贞丰县| 滦南县| 兴海县| 昭苏县| 克拉玛依市| 布尔津县| 西城区| 封开县| 易门县| 冕宁县| 武陟县| 重庆市| 平潭县| 额敏县| 杭锦后旗| 龙川县| 宝应县| 元江| 迁西县| 竹山县| 诸城市| 桐梓县| 独山县| 铅山县| 浙江省| 永平县| 寻甸| 文化| 新河县|