递归详解(二)

 1 public class A {
 2     static int k=0;
 3     public static void main(String args[]) {
 4         char[] ss = { '1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4',
 5                 '5', '6', '7' };
 6         permutation(ss, 0);
 7     }
 8     public static void permutation(char[] ss, int i) {
 9         
10         if (ss == null || i < 0 || i > ss.length) {
11             return;
12         }
13         if (i == ss.length) {
14             String a = new String(ss);
15             System.out.println(a);
16             k++;
17             if(k==6)
18             System.exit(0);
19         } else {
20             for (int j = i; j < ss.length; j++) {
21                 char temp = ss[j];// 交换前缀,使之产生下一个前缀
22                 ss[j] = ss[i];
23                 ss[i] = temp;
24                 permutation(ss, i + 1);
25                 temp = ss[j]; // 将前缀换回来,继续做上一个的前缀排列.
26                 ss[j] = ss[i];
27                 ss[i] = temp;
28             }
29         }
30     }
31 }

这个递归执行结果很多很多,结果为14!。前6个结果为:
12345671234567
12345671234576
12345671234657
12345671234675
12345671234765
12345671234756

下面分析一下过程:

这么讲吧:
permutation(ss, i);//初始调用时,i值等于0
为了方便说,后面调用permutation函数时,i值等于几,就叫几号递归
permutation(ss, 0);//0号递归开始执行      判断if条件语句不成立
运行else语句中的for循环,j=0,i<14,  //ss.length=14
调用permutation(ss, 0+1);

permutation(ss, 0+1););//1号递归开始执行      判断if条件语句不成立
运行else语句中的for循环,j=1,j<14,  //ss.length=14
调用permutation(ss, 1+1);

...

permutation(ss, 13+1););//14号递归开始执行      判断if条件语句成立
执行System.out.println(a); //a=12345671234567

14号递归不成立后,回归13号递归的for循环处,进行j++处理,
运行for循环,j=14,j<14,不成立

13号递归不成立后,回归12号递归的for循环处,进行j++处理,

运行for循环,j=13,j<14,成立。执行

char temp = ss[13];// 交换前缀,使之产生下一个前缀
    ss[13] = ss[12];
    ss[12] = temp;
    permutation(ss, 12 + 1);这段代码执行完以后,13位和12位进行换位

permutation(ss, 12+1););//13号递归开始执行      判断if条件语句不成立
运行else语句中的for循环,j=1,j<14,  //ss.length=14
调用permutation(ss, 13+1);

permutation(ss, 13+1););//14号递归开始执行      判断if条件语句成立
执行System.out.println(a); //a=12345671234576

。。。

描述起来挺麻烦,不再赘述,看图的话会明了许多:

 

 可以看出f(12)的入栈到出栈完成12位13位的排列;

可以看出f(11)的入栈到出栈完成11-13位的排列;

...

从而f(0)的入栈到出栈完成0-13位的排列;

排列过程也是有规律的,以567排列为例,先把5放首位,排列6,7;

再把6放首位,排列5,7;

最后把7放首位,排列5,6;这样3个数的排列就完成啦。

也可以通过程序检验执行上面逻辑的正确性,在程序中加入变量和p和q,用来记录入栈和出栈的次数:

System.out.println(p);
System.out.println(a);
System.out.println(q);
*
*
*
p++;
permutation(ss, i + 1);
q++;

下面给出前14组数据,读者自己结合上图揣摩规律

 1 14
 2 12345671234567
 3 0
 4 16
 5 12345671234576
 6 2
 7 19
 8 12345671234657
 9 5
10 21
11 12345671234675
12 7
13 24
14 12345671234765
15 10
16 26
17 12345671234756
18 12
19 30
20 12345671235467
21 16
22 32
23 12345671235476
24 18
25 35
26 12345671235647
27 21
28 37
29 12345671235674
30 23
31 40
32 12345671235764
33 26
34 42
35 12345671235746
36 28
37 46
38 12345671236547
39 32
40 48
41 12345671236574
42 34
原文地址:https://www.cnblogs.com/hixin/p/4134091.html