全排列算法(递归)

            一直学习,有时候会感到厌烦,天天呆在自习室,把人都傻了。考研刚刚结束,打算把数据结构再复习复习,也给自己找点编程的东西。接受了朋友的建议,先从递归算法开始复习吧。

       递归是一种机制,一种思想。有的问题本身就是递归定义的,例如求阶乘,二叉树……;有的问题表面上看来不是递归定义,但是也可以用递归来解决,我认为这有点像分治法,即减小问题的规模。实现递归,有两个必要条件,即1.确定递归公式;2.确定边界(终了)条件;

      例1:求n个元素的全排列?

      分析:按照排列组合的知识,我们知道结果有n!种。在这里,我为了便于自己分析,仅取[a,b,c],即令n=3。结果是:a,b,c;

       a,c,b;

       b,a,c;

       b,c,a;

       c,a,b;

       c,b,a.

首先,上述结果可以分为三组:

1、a跟着{b,c}的全排列

2、b跟着{a,c}的全排列

3、c跟着{a,b}的全排列

接下来,我们认真分析,可以发现,在上面所分的三个小组,有可以用同样的思想处理,即:

1、a跟着{b,c}的全排列

       (1)b跟着{c}的全排列

       (2)c跟着{b}的全排列

2、b跟着{a,c}的全排列

         与上相同……,嘿嘿,请自己想想吧

3、c跟着{a,b}的全排列

附上代码:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))
  4 void perm(char [],int,int);
  5 int main()
  6 {
  7     char list[]={'a','b','c'};
  8     perm(list,0,2);
  9     return 0;                                                                                                                      
 10 }   
 11 void perm(char list[],int i,int n)
 12 {
 13     int j=0,temp;
 14     if(i==n)
 15     {
 16         for(;j<=n;j++)
 17             printf("%c ",list[j]);
 18         printf("\n");
 19     }   
 20     else
 21     {
 22         for(j=i;j<=n;j++)
 23         {
 24             SWAP(list[i],list[j],temp);
 25             perm(list,i+1,n);
 26             SWAP(list[i],list[j],temp);
 27         }       
 28     }   
 29 } 

为了表明意思,我在纸上模拟了递归调用的执行过程,发现结果如下:

a,b,c

a,c,b

b,a,c

b,c,a

c,b,a

c,a,b

细心的读者可能会发现,最后两行不太一样,跟我们分析的不同,但是,这就是程序执行的结果,因为,在把以b开头的结果输出后,往上一层跳时,把数组还原为[a,b,c],接下来,在处理以c开头的结果时,第一层循环,应该先把a与c交换,再向下递归调用~~~

附上图片:



原文地址:https://www.cnblogs.com/javaadu/p/11742724.html