全排列算法实现

用递归的方法实现全排列

第一行输入n,代表元素个数
第二行输入n个整数,用空格分开
输出这n个数的全排列,每一行输出一个

思路:
可以运用递归的方法实现,先输出1个数字的全排列,再递归输出前2个数的全排列,一直到前n个数的全排列,这个时候其中一个全排列已经齐了,可以进行打印。
之后求前n-1个数字的全排列,不能有重复,假如前n-1个数不满足了,可以求前n-2个数的全排列,将最后两个数字换一下位置
比如,输入6个数字,3 2 5 6 7
第一个全排列:3 2 5 6 7
第二个全排列:3 2 5 7 6
第三个全排列:3 2 6 5 7
第四个全排列:3 2 6 7 5
…………

代码实现,带注释

#include<iostream>
using namespace std;
// a[]数组用来存放输入的数字
// b[]数组用来存放每一个全排列的结果,会一直变化
// vis[]数组用来存放a[]数组中每个值是否使用过
// countt用来记录n个数的时候,全排列的个数
int a[1010],b[1010],vis[1010],n,countt=0;
void print(){
    int i;
    // 打印其中一个全排列,由n个数字构成
    for(i=1;i<=n;i++){
        cout<<b[i]<<" ";
    }
    cout<<endl;
    // 每打印完一个全排列,计数器加一
    countt++;
}

// 这个递归用来求前x个数的全排列
void dfs(int x){
    int i;
    if(x<=n){
        for(i=1;i<=n;i++){
            // 如果这个数字没有用过,即vis[i]=0,则可以用
            if(!vis[i]){
                // 将a[i]的值存入b[i]
                b[x]=a[i];
                // 将vis[i]的值设为1,表示不能再用了
                vis[i]=1;
                // 递归求前x+1个数字的全排列
                dfs(x+1);
                // 回退一步
                vis[i]=0;
            }
        }
    }
    // 当x=n+1的时候,表示一个全排列已经齐了,可以进行打印了
    else{
        // 调用print打印函数
        print();
    }
}
int main(){
    int i,j,k;
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>a[i];
    }
    dfs(1);
    // 最后打印全排列的种类数量,为n!
    cout<<countt<<endl;
}

输入

6
3 2 5 6 7

输出结果

3 2 5 6 7 
3 2 5 7 6 
3 2 6 5 7 
3 2 6 7 5 
3 2 7 5 6 
3 2 7 6 5 
3 5 2 6 7 
3 5 2 7 6 
3 5 6 2 7 
3 5 6 7 2 
3 5 7 2 6 
3 5 7 6 2 
3 6 2 5 7 
3 6 2 7 5 
3 6 5 2 7 
3 6 5 7 2 
3 6 7 2 5 
3 6 7 5 2 
3 7 2 5 6 
3 7 2 6 5 
3 7 5 2 6 
3 7 5 6 2 
3 7 6 2 5 
3 7 6 5 2 
2 3 5 6 7 
2 3 5 7 6 
2 3 6 5 7 
2 3 6 7 5 
2 3 7 5 6 
2 3 7 6 5 
2 5 3 6 7 
2 5 3 7 6 
2 5 6 3 7 
2 5 6 7 3 
2 5 7 3 6 
2 5 7 6 3 
2 6 3 5 7 
2 6 3 7 5 
2 6 5 3 7 
2 6 5 7 3 
2 6 7 3 5 
2 6 7 5 3 
2 7 3 5 6 
2 7 3 6 5 
2 7 5 3 6 
2 7 5 6 3 
2 7 6 3 5 
2 7 6 5 3 
5 3 2 6 7 
5 3 2 7 6 
5 3 6 2 7 
5 3 6 7 2 
5 3 7 2 6 
5 3 7 6 2 
5 2 3 6 7 
5 2 3 7 6 
5 2 6 3 7 
5 2 6 7 3 
5 2 7 3 6 
5 2 7 6 3 
5 6 3 2 7 
5 6 3 7 2 
5 6 2 3 7 
5 6 2 7 3 
5 6 7 3 2 
5 6 7 2 3 
5 7 3 2 6 
5 7 3 6 2 
5 7 2 3 6 
5 7 2 6 3 
5 7 6 3 2 
5 7 6 2 3 
6 3 2 5 7 
6 3 2 7 5 
6 3 5 2 7 
6 3 5 7 2 
6 3 7 2 5 
6 3 7 5 2 
6 2 3 5 7 
6 2 3 7 5 
6 2 5 3 7 
6 2 5 7 3 
6 2 7 3 5 
6 2 7 5 3 
6 5 3 2 7 
6 5 3 7 2 
6 5 2 3 7 
6 5 2 7 3 
6 5 7 3 2 
6 5 7 2 3 
6 7 3 2 5 
6 7 3 5 2 
6 7 2 3 5 
6 7 2 5 3 
6 7 5 3 2 
6 7 5 2 3 
7 3 2 5 6 
7 3 2 6 5 
7 3 5 2 6 
7 3 5 6 2 
7 3 6 2 5 
7 3 6 5 2 
7 2 3 5 6 
7 2 3 6 5 
7 2 5 3 6 
7 2 5 6 3 
7 2 6 3 5 
7 2 6 5 3 
7 5 3 2 6 
7 5 3 6 2 
7 5 2 3 6 
7 5 2 6 3 
7 5 6 3 2 
7 5 6 2 3 
7 6 3 2 5 
7 6 3 5 2 
7 6 2 3 5 
7 6 2 5 3 
7 6 5 3 2 
7 6 5 2 3 
120
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值