问题描述
设计一个递归算法生成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)构成。
解题思路
1)在主函数中输入需要进行全排列的数字,并调用perm()函数;
2)在perm函数中实现递归
for循环将begin-end中的每个数放到begin位置中去
假设begin位置确定,那么对begin+1-end中的数继续递归
一到递归的出口就输出数组,此数组为全排列
递归之后,再交换,还原。
实现
(1)代码实现
#include "stdio.h"
#include "malloc.h"
void swap (int *a,int i1,int i2) {
int temp;
temp = a[i2];
a[i2] = a[i1];
a[i1] = temp;
return;
}
void perm(int *arr,int begin,int end){
int i,j;
if(begin==end-1){
for(i=0;i<end;i++){
printf("%d",arr[i]);
}
printf("\n");
return;
}
else{
for(j=begin;j<end;j++){
swap(arr,begin,j);
perm(arr,begin+1,end);
swap(arr,begin,j);
}
}
}
int main(){
int i,j,m=0;
int len;
int * arr;
printf("请输入数组长度:");
scanf("%d", &len);
arr = (int *)malloc(sizeof(int)*len);
printf("请输入数组的值:");
for(i=0;i<len;i++){
scanf("%d", &arr[i]);
m++;
}
if(m==len){
perm(arr,0, len);
}
else
{
printf("输入的数组的长度与之前输入的数字不符!");
}
free(arr);
return 0;
}