今日来连连碰到递归算法的使用,于是自己便花时间看了一下。以下作为总结:
学过程序设计的朋友都知道,存在自调用的算法称作递归算法。递归算法设计的基本思想是:对于一个复杂的问题,把源问题分解为若干个相对简单类同的子问题,继续下去直到子问题简单到能够直接求解,也就是说到了递归的出口,这样源问题就有递归的解。
1、阶乘的求法。最简单的,也是最经典的题目。
package 递归; public class rec1 { /** * @param 求解n! */ public static void main(String[] args) { rec1 rec1 = new rec1(); System.out.println(rec1.fun(5)); } public int fun(int num){ if(num==1) return 1; return num*fun(num-1); } }
2、给定一个n(n<5000),不停的*2一直到结果>5000为止,然后输出这一连串的数字。如n=3,output:3,6,12,24,48,96,192,384,768,1536,3072。使用循环当然可以但是我们这里使用递归的方法来完成。
package 递归; public class rec2 { public static void main(String[] args) { rec2 rec2 = new rec2(); rec2.fund(3); } public void fund(int i){ if((i<<1)<5000) { //左移位相当于*2 System.out.print((i)+","); fund(i<<1); } else { System.out.print((i)); return; } } }
3、一个射击运动员打靶, 靶一共有 10 环, 连开 10 枪打中 90 环的可能性有多少种?可以使用10层嵌套,但是我们使用递归的方法解决问题。
package 递归; public class rec3 { public static void main(String[] args) { rec3 rec3 = new rec3(); rec3.fun(90, 9); System.out.println(rec3.cnt); } private int cnt= 0; public void fun(int score,int num){ if(score<0||score>(num+1)*10) return; //查看是否需要继续下去 if(num==0) { cnt++; return; }; for(int i=0;i<=10;i++) fun(score-i,num-1); } }
4、排列组合问题的解决。如{1,2,3,4,5,6} 一共有1*2*3*4*5*6中排列方式,请将他们依次输出。
package 递归; public class rec4 { /* * 获取排列组合的方法 */ public static void main(String[] args) { int data[] = {1,2,3,4,5,6}; rec4 rec4 = new rec4(); rec4.fun("",data); System.out.println(rec4.sum); } private int sum = 0 ; public void fun(String prefix,int[]data){ int len = data.length; if(len== 1) { System.out.println(prefix +data[0]); sum++; return; } for(int i=0;i<len;i++){ int res [] = new int[len-1]; int k = 0 ; for(int j=0;j<len;j++){ if(j!=i) res[k++]=data[j]; } fun(prefix + data[i],res); } } }
5、汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。汉诺塔要求:将第一座塔上的所有盘子,借助第二座塔,全部搬运到第三座塔上。规则:一次只能搬运一个盘子,不准将大盘子落在小盘子上。
package 递归; public class rec5 { public static void main(String args[]) { rec5 rec5 = new rec5(); rec5.fun(4, 'A', 'B', 'C'); System.out.println("一共有" + rec5.cnt + "中方法"); } private int cnt = 0; public void fun(int topN, char from, char inter, char to) { if (topN == 1)// 将最后一个圆盘放到最终位置 { System.out.println(" DISK 1 FROM " + from + " TO " + to); cnt++; } else { fun(topN - 1, from, to, inter);// 借助于目标位置先将除最后一个圆盘的所有圆盘放在中间位置 System.out.println(" DISK " + topN + " FROM " + from + " TO " + to); cnt++; fun(topN - 1, inter, from, to);// 借助于初始位置将已经处于中间位置的除最后一个圆盘的所有圆盘放在目标位置 } } }