全排列(深度優先搜索非遞歸實現)

前段時間面試了一家公司的圖像崗位,居然盡問我C++的知識,還讓我寫全排列,表示無語……,不過還是硬着頭皮寫了下,這麼久沒接觸算法,之前也沒寫過全排列,汗顏呀,回來還發現寫法有些low,貼出當時的代碼,mark下學業不精的尷尬,順便熟悉一下MarkDown,以後再也不用Word寫博客了,

題目

輸出 1,2,…,N的全排列

樣例

這裏寫圖片描述
基本思路是DFS,考慮到遞歸的棧消耗,於是用數組來實現非遞歸,時間複雜度爲N! ,上代碼:

  • flag: 是否已經選中的標記,已經選擇了爲1,否則爲0
  • state: 記錄上一次搜索到的數字
  • data: 存放全排列
#include"iostream"
#include <iomanip>
using namespace std;
void fullPerm(int N)
{
    int *flag=new int [N];
    int *state=new int[N];
    int *data = new int[N];

    memset(flag,0,sizeof(int)*N);
    memset(state, 0, sizeof(int)*N);
    int d = 0;
    int cnt = 1;
    while (true)
    {
        if (N == d)//到底了
        {
            cout <<setw(3)<<cnt++<<": ";
            for (int i = 0; i < N; i++)
                cout << data[i]+1 << " ";
            cout << endl;
            d--;//回溯
            flag[state[d]] = 0;//上去的時候釋放選中的元素
            state[d]++;
        }
        else
        {
            int s = state[d];
            for (; s < N; s++)//尋找下一個沒有被選中的元素
            {
                if (0 == flag[s])//往下搜索
                {
                    data[d] = s;
                    flag[s] = 1;//下來的時候選擇元素
                    state[d] = s;
                    d++;
                    break;
                }
            }
            if (s == N)//中間層回溯
            {
                state[d] = 0;
                d--;
                if (d < 0)//回溯到了最頂層
                    break;
                flag[state[d]] = 0;
                state[d]++;
            }
        }
    }
    delete[] flag;
    delete[] state;
    delete[] data;
}
void main(void)
{
    int n;
    cin >> n;
    fullPerm(n);
    system("pause");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章