给定由n(n>=1) 个元素组成的集合,输出该集合所有可能的排列。 共有n!种排列可能,其中递归线索就是“后面隔着...的所有排列”,这表明,如果能够解决n-1个元素集合的排列问题,就可以解决n个元素集合的排列问题。将这些分析结合起来考虑,就形成了如程序所示的算法。
其中假定list是一个字符数组,可以看到,程序递归地产生排列知道i=n,初始函数调用是perm(list, 0, n-1)
#include<stdio.h>
#define SWAP(x, y, t) ((t) = (x), (x) = (y), (y)=(t))
void generate(char *list, int i, int n){
int j, temp;
if(i == n){
// printf("0#test i = [%d] list[%c%c%c]\n", i, list[0],list[1],list[2]);
for(j = 0; j <= n; j++)
printf("%c",list[j]);
printf(" \n");
}else{
for(j =i; j <=n ; j++){
// printf("1#test i = [%d] j = %d list[%c%c%c]\n", i,j, list[0],list[1],list[2]);
SWAP(list[i], list[j], temp);
//printf("2#test i = [%d] j = %d list[%c%c%c]\n", i,j, list[0],list[1],list[2]);
generate(list, i+1, n);
// printf("3#test i = [%d] j = %d list[%c%c%c]\n", i,j, list[0],list[1],list[2]);
SWAP(list[i], list[j], temp);
//printf("4#test i = [%d] j = %d list[%c%c%c]\n", i,j, list[0],list[1],list[2]);
}
}
}
int main(){
char a[]={'a', 'b', 'c'};
generate(a, 0, 2);
return 0;
}
输出结果:
abc
acb
bac
bca
cba
cab
这个递归比较复杂递归内嵌套着循环,i每次为2时打印信息,“递”结束 开始“归”。核心思想是想求n个元素的全排列,
只需求的n-1个元素的排列。所以3个元素的全排列问题,只要对数组下标1、2位置的元素做全排列即可。