递归生成全排列
2011-11-10 14:02
99 查看
设R={r1,r2,……rn}是要进行排列的n个元素,Ri=R-{r}。
集合x中元素的全排列记为Perm(X).(ri)Perm(X)表示在全排列Perm(X)的每一个排列前加上前缀ri得到的排列。
R的全排列可归纳定义如下:
当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素。
当n>1时,Perm(R)由(r1)Perm(R1),(r2)Perm(R2),……,(rn)Perm(Rn)构成。
算法Perm(list,k,m)递归地产生所有前缀是list[0:k-1],且后缀是list[k:m]的全排列的所有排列。函数调用Perm(list,0,n-1)则产生list[0:n-1]的全排列。 在一般情况下,k<m.算法将list[k:m]中的每一元素分别与list[k]中的元素交换。然后递归地计算list[k+1:m]的全排列,并将计算结果作为list[0:k]的后缀。
集合x中元素的全排列记为Perm(X).(ri)Perm(X)表示在全排列Perm(X)的每一个排列前加上前缀ri得到的排列。
R的全排列可归纳定义如下:
当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素。
当n>1时,Perm(R)由(r1)Perm(R1),(r2)Perm(R2),……,(rn)Perm(Rn)构成。
#include<stdio.h> int sum; void swap(int *a,int *b) { int temp=*a; *a=*b; *b=temp; } void perm(int list[],int k,int m) { //产生list[k:m]的所有排列 int i; if(k==m) { //只剩下一个元素 for(i=0;i<=m;i++) printf("%d ",list[i]); printf("\n"); sum++; } else //还有多个元素待排列,递归产生排列 { for(i=k;i<=m;i++) { swap(&list[i],&list[k]);//将第i个元素作为第一个 perm(list,k+1,m); swap(&list[i],&list[k]);//将第i个元素换回原来的位置,准备用第i+1个做第一个 } } } int main() { int n; int list[20]; while(scanf("%d",&n)!=EOF) { sum=0; for(int i=0;i<n;i++) { list[i]=i+1; } perm(list,0,n-1); printf("sum = %d \n",sum); } return 0; }
算法Perm(list,k,m)递归地产生所有前缀是list[0:k-1],且后缀是list[k:m]的全排列的所有排列。函数调用Perm(list,0,n-1)则产生list[0:n-1]的全排列。 在一般情况下,k<m.算法将list[k:m]中的每一元素分别与list[k]中的元素交换。然后递归地计算list[k+1:m]的全排列,并将计算结果作为list[0:k]的后缀。
相关文章推荐
- 递归生成全排列(常规)
- 生成8位26个字母和数字的全排列(密码字典,密钥)c++代码(非递归高效直接)
- 递归解决全排列生成算法
- 递归解决全排列生成算法
- 递归生成集合的全排列
- 非递归生成全排列
- 递归解决全排列生成算法
- sdut oj 1163 C语言实验——排列 (当初不会递归生成排列,这个题目现在才补上 刘汝佳给出了写法 *【模板】 当然有生成全排列的函数存在 )
- 生成n个数的全排列【递归、回溯】
- 生成所有全排列 非递归和递归实现
- 简单探讨全排列的递归生成算法
- 全排列生成算法(非递归)
- 全排列问题之递归求解
- 全排列--字典序列、递归方法c语言实现
- 算法——递归生成集合的所有组合
- 使用STL的next_permutation函数生成全排列(C++)
- 全排列生成算法:next_permutation
- 全排列的递归实现
- 全排列(Perm)的递归实现算法
- 运用递归求n个元素的全排列