全排列(深度优先搜索非递归实现)

前段时间面试了一家公司的图像岗位,居然尽问我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");
}

猜你喜欢

转载自blog.csdn.net/soidnhp/article/details/44495491