全排列问题(递归C++实现)

一、题目

按字典序生成1~n的全排列

二、解题思路

我们尝试用递归的思想解决: 先输出所有以1开头的排列( 这一步是递归调用) , 然后输出以2开头的排列( 又是递归调用) , 接着是以3开头的排列……最后才是以n 开头的排列。
以1开头的排列的特点是: 第一位是1, 后面是2~n的排列。 根据字典序的定义, 这些2~n的排列也必须按照字典序排列。 换句话说, 需要“按照字典序输出2~n的排列”, 不过需注意的是, 在输出时, 每个排列的最前面要加上“1”。 这样一来, 所设计的递归函数需要以下参数:

  • 已经确定的“前缀”序列。
  • 元素的标记数组,标记出已使用元素和未使用元素,从未使用的数组选出元素,加入前缀数组。

这样可以得到一个伪代码:

void dfs(容器A, 标记数组S)
{
    if(容器A中的元素个数为N){
        输出容器A中的元素;
    } 
    //按照从小到大的顺序依次考虑S的未使用的元素v
    else
    {
        dfs(在A的末尾填加v后得到的新序列, S-{v});
    }
}

三、代码编写 

#include <iostream>
#include <vector>

#define N 5


using namespace std;

//需要全排列的数组,必须按递增顺序
int a[N] = {-1,1,2,3,4};


//输出一个排列
void print(vector<int> vec){
    vector<int>::iterator it = vec.begin();
    for(it ; it != vec.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;
}
//递归生成全排列
void dfs(vector<int>& vec,bool flag[]){
    if(vec.size() == N-1){
        print(vec);
    }
    else{
        for(int i=1;i<N;i++){
            //如果没有访问,则访问
            if(flag[i] == false){
                //将元素加入vector容器中
                vec.push_back(a[i]);
                //标记已访问
                flag[i] = true;
                //继续递归
                dfs(vec,flag);
                //回溯
                vec.pop_back();
                flag[i] = false;
            }
        }
    }
}


int main()
{
    bool flag[N] = {false};
    vector<int> vec;
    dfs(vec,flag);

    return 0;
}

四、运行结果

 

发布了46 篇原创文章 · 获赞 48 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_39559641/article/details/99053042