废话:

这里前两种是处理无重复元素的全排列,最后一种是都可以处理,哈哈,如果不想看前两种,直接看最后一种吧,但还是建议读者学会前两种,有益无害,本蒟蒻的思路来自我的老师 ,听老师的培训来写的 老师博客

1交换法

#include <iostream>
using namespace std;
int n=3 ;
int cnt = 0;
void Permutation(char *s,int p)//从数组s的第p个位置开始全排列
{
    if(p==n)
    {
        printf("%s\n",s);
        cnt++;
        return ;
    }
    for(int i=p;i<n;i++)
    {
        swap(s[i],s[p]);//每个字符都有成为当前起始字符的机会
        Permutation(s,p+1);
        swap(s[i],s[p]);//返回初始状态,才能保证后面的交换是正确的, 回溯
    }
}
int main()
{
    char s[5] = "abc";
    Permutation(s,0);
    cout<<cnt<<endl;
    return 0;
}

2抽取法(dfs实现)

这种方法想必学过dfs都知道,哈哈哈哈

#include <iostream>
using namespace std;
int n=3 ;
int cnt = 0;//统计全排列种类数
char tmp[5]="";//定义一个临时数组来保存抽取到的元素
char s[5] = "abc";
int used[5];//used[i]判断抽取过第i个元素
void dfs(int p)
{
    if(p==n)
    {
        printf("%s\n",tmp);
        cnt++;
        return ;
    }
    for(int i=0;i<n;i++)
    {
       if(!used[i])//没有使用过
       {
           tmp[p] = s[i];
           used[i] = 1;//标记为使用过
           dfs(p+1);
           used[i] = 0;//回溯
       }
    }
}
int main()
{
    dfs(0);
    cout<<cnt<<endl;
    return 0;
}

STL 大杀器(一定要看)

     next_permutation:数组元素初始必须是升序的,
                       输出也是按字典序升序的
     prev_permutation:数组元素初始必须是降序的,
                       输出也是按字典序降序的
     头文件:#include<algorithm>

优点:自动排序,自动去重, 代码少, 不容易犯错,推荐使用,这里本蒟弱推荐大家都使用这个

next_permutation:

#include <iostream>
#include<algorithm>//头文件
using namespace std;
int main()
{
    char s[5] = "abc";
    int cnt = 0;
    do
    {
        cout<<s<<endl;
        cnt++;
    }while(next_permutation(s,s+3));//起始位置,左闭右开
    cout<<"总共有:"<<cnt<<" 种排列"<<endl;
    return 0;
}

升序排

:prev_permutation

#include <iostream>
#include<algorithm>//头文件
using namespace std;
int main()
{
    char s[5] = "cba";
    int cnt = 0;
    do
    {
        cout<<s<<endl;
        cnt++;
    }while(prev_permutation(s,s+3));//起始位置,左闭右开
    cout<<"总共有:"<<cnt<<" 种排列"<<endl;
    return 0;
}

按降序排的