全排列问题的递归算法(Perm)

题目】设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列。

算法讲解

设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}。
集合X中元素的全排列记为perm(X)。
(ri)perm(X)表示在全排列perm(X)的每一个排列前加上前缀得到的排列。
R的全排列可归纳定义如下:
当n=1时,perm(R)=(r),其中r是集合R中唯一的元素;
当n>1时,perm(R)由(r1)perm(R1),(r2)perm(R2),…,(rn)perm(Rn)构成。
实现思想:将整组数中的所有的数分别与第一个数交换,这样就总是在处理后n-1个数的全排列。

示例

当n=3,并且E={a,b,c},则:
perm(E)=a.perm({b,c}) + b.perm({a,c}) + c.perm({a,b})
perm({b,c})=b.perm(c) + c.perm(b)
a.perm({b,c})=ab.perm(c) + ac.perm(b)
=ab.c + ac.b=(abc, acb)

核心代码

template<class Type>
void Perm(Type list[],  int k, int m )
{ //产生[list[k:m]的所有排列
    if(k==m)
     {  //只剩下一个元素
         for (int i=0;i<=m;i++)
     cout<<list[i];
         cout<<endl;
    }
    else  //还有多个元素待排列,递归产生排列
       for (int i=k; i<=m; i++)
        {
           swap(list[k],list[i]);
           Perm(list,k+1,m);
           swap(list[k],list[i]);
         }
}

完整代码

#include <iostream>
#include <algorithm>

using namespace std;

template<class Type>
void Perm(Type list[],  int k, int m )
{ //产生[list[k:m]的所有排列
    if(k==m)
     {  //只剩下一个元素
         for (int i=0;i<=m;i++)
     cout<<list[i];
         cout<<endl;
    }
    else  //还有多个元素待排列,递归产生排列
       for (int i=k; i<=m; i++)
        {
           swap(list[k],list[i]);
           Perm(list,k+1,m);
           swap(list[k],list[i]);
         }
}

int main() {

    char s[]="abc";
    Perm(s,0,2);

    return 0;
}
时间: 2024-10-09 04:29:35

全排列问题的递归算法(Perm)的相关文章

全排列的非递归算法

1.全排列的定义和公式: 从n个数中选取m(m<=n)个数按照一定的顺序进行排成一个列,叫作从n个元素中取m个元素的一个排列.由排列的定义,显然不同的顺序是一个不同的排列.从n个元素中取m个元素的所有排列的个数,称为排列数.从n个元素取出n个元素的一个排列,称为一个全排列.全排列的排列数公式为n!,通过乘法原理可以得到. 2.时间复杂度: n个数(字符.对象)的全排列一共有n!种,所以全排列算法至少时间O(n!)的.如果要对全排列进行输出,那么输出的时间要O(n?n!),因为每一个排列都有n个数

全排列算法-c++实现

递归算法:n个元素的全排列=n x (n-1)个元素的全排列. 非递归算法:求一个排列的下一个字典序排列,stl已经有的next_permutation()函数. #include <iostream> #include <algorithm> using namespace std; int main(){ int arr[4]={1,2,3,4}; do{ for(int i = 0; i < 4; i++){ cout << arr[i] <<

算法(全排列算法封装)

本算法是教材中的全排列方法之一,本人仅做封装,在此感谢发现算法和传播算法的大牛们. /// <summary> /// 全排列算法,算法原理:Perm(n)=[n]*Pern(n-1).N的全排列等于将N个数取一个放在第N个位置后,剩下的N-1个数做全排列. /// 这个算法的一个用途是进行行列式的展开和计算,这也是这次封装这个算法的目的. /// </summary> public class Permulation { /// <summary> /// 排列结果

全排列算法(递归)

全排列算法是一种经典的递归算法.例如集合{a,b,c}的全排列为{(a,b,c).(a,c,b).(b,a,c).(b,c,a).(c,b,a).(c,a,b)}共3!种. 递归法求解的思路是先固定第一个元素,求剩下的全排列,求剩下的全拍列时,固定剩余元素中的第一个元素,再求剩下元素的全排列,直到就剩一个元素停止. 例如求集合{a,b,c,d}的全排列. 1.固定元素a求{b,c,d}元素的全排列 (1).固定元素b求{c,d}的全排列 1).固定元素c ,得到一个排列方式(a,b,c,d) 2

全排列 递归实现

前面我们介绍了全排列的非递归算法,现在我再来写一下全排列的递归算法: 这两种算法的算法思路并不相同.递归算法的思路比较接近于我们现实生活中的思路. 1.试想,我们只有两个数字:12.要对它进行全排列,第一种方式就是12本身,第二种,将12交换,变为21即可.这提示了我们一种交换的思路. 2.但这概括的并不全面.试想,我们要对123进行全排列.我们可以采用将1固定,"23"进行全排列,将"2"固定,对"13"进行全排列.将"3"

【codeup】1959: 全排列 及全排列算法详解

题目描述 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列.我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列. 输入 输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间. 输出 输出这个字符串的所有排列方式,每行一个排列.要求字母序比较小的排列在前面.字母序如下定义:已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存

python 全排列

itertools模块现成的全排列: for i in itertools.permutations('abcd',4): print ''.join(i) 相关全排列算法: def perm(l): if(len(l)<=1): return [l] r=[] for i in range(len(l)): s=l[:i]+l[i+1:] p=perm(s) for x in p: r.append(l[i:i+1]+x) return r 版权声明:本文为博主原创文章,未经博主允许不得转载.

有重复元素的排列问题

问题描述:设R={r1,r2,···,rn}是要进行排列的n个元素.其中元素r1,r2···rn可能相同.试设计一个算法,列出R的所有不同排列 算法设计:给定n及待排列的n个元素,计算出这n个元素的所有不同排列 设计思路:共有m个数的数组,排列到第k位时查看数组下标从k到m的数中是否有数字与下标为k的数字相等,相等的不交换,不相等则交换得新排列 #include<stdio.h> #include<stdlib.h> #include <string.h> void S

例题1.4 排列问题

题目 已知集合R={r1,r2,-,rn},请设计一个算法生成集合R中n个元素的全排列. 思路 令Rj=R-{rj} 记集合X中元素的全排列记为perm(X).那么(rj)perm(X)表示在全排列perm(X)的每一种排列前加上前缀rj所得到的全排列.所以,R的全排列可归纳为 perm(R)={ r1     当n=1 (r1)perm(R1)+(r2)perm(R2)+-+(rn)perm(Rn)   当n>1 } function swap(a,i,j){ var temp=a[i] a[