利用遞歸實現排列,比如實現字符數組list[]=“abc”的排列,方法的思想是,a開頭,後面bc所有排列,然後b開頭後面ac所有排列,然後c開頭後面ba所有排列。
以下是例子代碼,這裏涉及到了遞歸調用裏面含有for循環的問題。遞歸調用裏含有for循環,也就是在for循環裏面進行了遞歸調用。這個時候可以理解成多層遞歸,例如下面例子中,第一層遞歸時開始執行第一次for循環,執行for循環時候開始了第二層遞歸,第二層遞歸裏開始執行第二層遞歸的for循環,第二層遞歸裏的for循環開始執行第三層遞歸,當第三層遞歸執行時發現k=j也就是滿足遞歸結束條件,則此時第三層遞歸結束,開始執行第二層遞歸的第二次for循環......當第二層遞歸結束後,開始執行第一層遞歸的第二次循環................
#include <stdio.h>
#define SWAP(a,b,t) ((t)=(a),(a)=(b),(b)=(t))//宏函數
void perm(char *list,int k,int j);
void main()
{
char list[]="abc";
perm(list,0,2);//0表示從a開始,2表示到c結束
}
void perm(char *list,int k,int j)//k,j爲開始結束位置
{
char temp;
int i;
if(k==j)
{
printf("%s\n",list);
}
else
{
for(i=k;i<=j;i++)
{
SWAP(list[i],list[k],temp);//換到開頭
perm(list,k+1,j);//遞歸調用
/*
遞歸調用,只有k變,可以理解成先把a放在開頭,把bc全排列,bc全排列的時候又要把b放在bc的開頭,把c全排列,以此類推。
當a在開頭時所有全排列完畢,也就是k=j時第三層遞歸結束進行第一層遞歸的第二次循環,也就是進行下一次for循環,把b放在開頭,全排列ac.....如此進行
*/
SWAP(list[i],list[k],temp);//恢復位置
}
}
}