递归算法解决全排列问题

全排列(permutation)的有关问题,拿数字为例(123的全排列)有
123 132
213 231
312 321
(1234的全排列)
1: 1234 1243 1324 1342 1423 1432 //黑体部分恰好为剩下三个数的全排列
2: 2134 2143 2314 2341 2413 2431
3: 3124 3142 3214 3241 3412 3421
4: 4123 4132 4213 4231 4312 4321

#include
using namespace std;
void perm(int a[],int k,int m)//对数组a[]从k到m
{
    if(k==m)//已经排完一种情况并输出
    {
        cout<>a;
    perm(a,0,3);
    return 0;
}

但此时输出结果的顺序,与预列的不一致
原因是代码中交换的步骤,比如当i=2时将a[0]与a[2]进行交换:
此时a[0]=3,再对a[1]到a[3](2,1,4)进行全排列,将会输出
3214
3241
3124
3142
3421
3412

下面的方法是利用深度优先算法,对char型数组的字典序全排列

全排列
描述
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有’a’ < ‘b’ < … < ‘y’ < ‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。
输入
输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
输出
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:
已知S = s1s2…sk , T = t1t2…tk,则S < T 等价于,存在p (1 <= p <= k),使得
s1 = t1, s2 = t2, …, sp - 1 = tp - 1, sp < tp成立。
样例输入
abc
样例输出
abc
acb
bac
bca
cab
cba

#include
#include
using namespace std;
int vis[10]={
     0};  //记录某元素是否遍历
char a[10],b[10];
int n;
void perm(int step)
{
     
    if(step==n)
    {
     
        cout<<b<<endl;
    }
    else
        for(int i=0;i<n;i++)
    {
     
        if(vis[i]==0)//如果没有被遍历
        {
     
            vis[i]=1;//标记
            b[step]=a[i];//存储在b数组里
            perm(step+1);//递归
            vis[i]=0;//恢复
        }
    }
}
int main()
{
     
    cin>>a;
    n=strlen(a);
    perm(0);
    return 0;
}

你可能感兴趣的:(算法,递归法)