keenlog

递归用法之“全排列算法”

简介:

  用递归写出全排列算法也不简是什么新问题了,网上随便一搜就能发现很多。本文就其中的一种算法——个人认为代码量最少的一种——进行一些基本的解释,以便有兴趣的读者能理清思路,共同探讨递归的妙用。


全排列的过程:

  简单起见,我们假设只要对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;
}

  


posted on 2011-09-04 12:24  keenlog  阅读(1258)  评论(2)    收藏  举报

导航