递归用法之“全排列算法”
简介:
用递归写出全排列算法也不简是什么新问题了,网上随便一搜就能发现很多。本文就其中的一种算法——个人认为代码量最少的一种——进行一些基本的解释,以便有兴趣的读者能理清思路,共同探讨递归的妙用。
全排列的过程:
简单起见,我们假设只要对ABCD四个字母进行全排列操作。运用递归的方法我们先假想有一个函数P当输入是ABC时能对ABC进行全排列操作。在这个基础上我们可先把ABC输入函数P,那么我们得到一组以D结尾的排列{ABC}D,其中{ABC}在本文表示对ABC的全排列。然后让D和A进行交换,这样ABCD的次序就变成了DBCA;我们再把头三个字母DBC输入函数P,那么我们得到另一组以A结尾的排列{DBC}A;
依次交换不同的字母还可以分别得到{ADC}B,{ABD}C。
如此,我们实际上就已经对ABCD作了全排列操作,那么这个操作本身恰就是函数P。
为了保持一贯性,我们要对以上过程做一个小小的修改。即,一开始时跳过生成{ABC}D的步骤而直接让D先与A交换然后进行低一级的全排列运算生成{DBC}A。那我们{ABC}D怎么来呢?不妨,最后一步让D与D自己交换,再把头三个字母喂给函数P后产后的输出就是{ABC}D了!
伪代码:
/*
*permut为全排列的递归函数
*data为完整的序列
*len为要进行全排列操作的长度
*/
permut (data, len)
if len=1 then
打印完整的data //长度为1时不进行排列,选择此时打印
return
endif
for i=0;i<len;i++
交换data[i]与data[len-1]
permut(data, len-1) //进入下一级递归
交换data[i]与data[len-1] //保证permut结束后原字母次序不被打乱
endfor
end
至于打印的时机为什么选在长度为1的时候我必须做流程图才能讲清楚。请原谅我一时的不负责,找时间我一定会补上。
c语言源代码:
View Code
#include<stdio.h>
void swap(char* x, char* y){
char tmp;
tmp=*x;
*x=*y;
*y=tmp;
}
void permut(char* data, int len){
int i;
if(len==1){
printf("%s\n",data);
return;
}
for(i=0;i<len;i++){
swap(&data[i],&data[len-1]);
permut(data,len-1);
swap(&data[i],&data[len-1]);
}
}
int main(void){
char A[]="ABCD";
permut(A,4);
return 1;
}

浙公网安备 33010602011771号