java-递归算法
2017-07-31 17:11
896 查看
一.基本定义
递归的效率差,但可以很方便的表达,做一些数学计算
1.求阶层
图示
求n!代码区
四种方法
2.求Fibonacci序列
1.定义:
0, 1, 1, 2, 3, 5, 8, 13, 21, …;
f0 = 0, f1 = 1, fn= fn−1 + fn−2 for n ≥ 2.
3.汉诺塔问题
汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?
第一步:将n-1个盘子从A柱移动至B柱(借助C柱为过渡柱)
第二步:将A柱底下最大的盘子移动至C柱
第三步:将B柱的n-1个盘子移至C柱(借助A柱为过渡柱)
func:
if n!=0 then ;预定值
func(n-1, a, c, b) ;将n-1个盘子由a移动到b,以c为辅助柱子(注意参数顺序)
move a
to c ;将a上的最后一个盘子移动到c
func(n-1, b, a, c) ;将n-1个盘子由b移动到c,以a为辅助柱子
endif ;完成
方法二:
下面是使用Java实现的汉诺塔程序,程序使用Stack实例来保存每个柱子上的盘子及它们的顺序。Stack是队列的一种,其中的元素遵循“先进先出”(FIFO)的原则,即不允许从队尾取元素。这种队列通常也称为“栈”。栈对元素的进出约定与汉诺塔的规则一致。
resolve方法用来移动盘子,参数n表示要移动的盘子的数量,a是盘子所在的柱子,b是辅助柱子,c是目标柱子。注意此方法会首先检查参数n,当n为0时直接返回,这就是前面所说的“预定值”。如果没有对预定值的判断,resolve的递归过程将不会自然终止,而是无限进行下去,直到塞满系统内存堆栈而导致程序奔溃。
另外要注意的是程序将盘子的初始数量设为32个,你可以修改该值,但建议不要设置的过大,原因正如前面所计算的那样,如果采用64个圆盘,你将至少需要数百年才能看到结果(更可能的结果是由于步数太多,系统没有足够的内存而导致程序奔溃)。
递归的效率差,但可以很方便的表达,做一些数学计算
1.求阶层
图示
求n!代码区
import java.util.Scanner; public class Test { public static int Factorial(int n) { if (n < 0) { System.out.println("无效输入,请重新输入!"); return 0; } else if (n == 1 || n == 0) { return 1; } else return n * Factorial(n - 1); } public static void main(String[] args) { System.out.println("input an integer: "); Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); System.out.println("the factorial of "+n+" is "+Factorial(n)); } }
四种方法
import java.math.BigInteger;//导入类 import java.util.ArrayList; import java.util.List; public class Test {//操作计算阶乘的类 public static int simpleCircle(int num){//简单的循环计算的阶乘 int sum=1; if(num<0){//判断传入数是否为负数 throw new IllegalArgumentException("必须为正整数!");//抛出不合理参数异常 } for(int i=1;i<=num;i++){//循环num sum *= i;//每循环一次进行乘法运算 } return sum;//返回阶乘的值 } public static int recursion(int num){//利用递归计算阶乘 int sum=1; if(num < 0) throw new IllegalArgumentException("必须为正整数!");//抛出不合理参数异常 if(num==1){ return 1;//根据条件,跳出循环 }else{ sum=num * recursion(num-1);//运用递归计算 return sum; } } public static long addArray(int num){//数组添加计算阶乘 long[]arr=new long[21];//创建数组 arr[0]=1; int last=0; if(num>=arr.length){ throw new IllegalArgumentException("传入的值太大");//抛出传入的数太大异常 } if(num < 0) throw new IllegalArgumentException("必须为正整数!");//抛出不合理参数异常 while(last<num){//建立满足小于传入数的while循环 arr[last+1]=arr[last]*(last+1);//进行运算 last++;//last先进行运算,再将last的值加1 } return arr[num]; } public static synchronized BigInteger bigNumber(int num){//利用BigInteger类计算阶乘 ArrayList list = new ArrayList();//创建集合数组 list.add(BigInteger.valueOf(1));//往数组里添加一个数值 for (int i = list.size(); i <= num; i++) { BigInteger lastfact = (BigInteger) list.get(i - 1);//获得第一个元素 BigInteger nextfact = lastfact.multiply(BigInteger.valueOf(i));//获得下一个数组 list.add(nextfact); } return (BigInteger) list.get(num);//返回数组中的下标为num的值 } public static void main(String []args){//java程序的主入口处 int num=5; int num1=23; System.out.println("简单的循环计算"+num+"的阶乘为"//调用simpleCircle +simpleCircle(num)); System.out.println("利用递归计算"+num+"的阶乘为"//调用recursion +recursion(num)); System.out.println("数组添加计算"+num+"的阶乘为"//调用addArray +addArray(num)); System.out.println("利用BigInteger类计算"+num1+"的阶乘为"//调用bigNumber +bigNumber(num1)); } }
2.求Fibonacci序列
1.定义:
0, 1, 1, 2, 3, 5, 8, 13, 21, …;
f0 = 0, f1 = 1, fn= fn−1 + fn−2 for n ≥ 2.
import java.util.Scanner; public class Fibonacci{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入一个大于零的整数:"); int n = sc.nextInt(); System.out.println("斐波那契数列为:"); for (int j = 1; j <= n; j++) { System.out.print(fibonacci(j)+" "); } //sc.close(); } private static int fibonacci(int i) { if (i == 1 || i == 2){ return 1; }else{ return fibonacci(i - 1) + fibonacci(i - 2); } } }
3.汉诺塔问题
汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?
第一步:将n-1个盘子从A柱移动至B柱(借助C柱为过渡柱)
第二步:将A柱底下最大的盘子移动至C柱
第三步:将B柱的n-1个盘子移至C柱(借助A柱为过渡柱)
func:
if n!=0 then ;预定值
func(n-1, a, c, b) ;将n-1个盘子由a移动到b,以c为辅助柱子(注意参数顺序)
move a
to c ;将a上的最后一个盘子移动到c
func(n-1, b, a, c) ;将n-1个盘子由b移动到c,以a为辅助柱子
endif ;完成
public class Hanio { public static void main(String[] args){ int i=3; char a ='A',b='B',c='C'; hanio(i,a,b,c); } public static void hanio(int n,char a,char b,char c){ if(n==1) System.out.println("移动"+n+"号盘子从"+a+"到"+c); else{ hanio(n-1,a,c,b);//把上面n-1个盘子从a借助b搬到c System.out.println("移动"+n+"号盘子从"+a+"到"+c);//紧接着直接把n搬动c hanio(n-1,b,a,c);//再把b上的n-1个盘子借助a搬到c } } }
方法二:
下面是使用Java实现的汉诺塔程序,程序使用Stack实例来保存每个柱子上的盘子及它们的顺序。Stack是队列的一种,其中的元素遵循“先进先出”(FIFO)的原则,即不允许从队尾取元素。这种队列通常也称为“栈”。栈对元素的进出约定与汉诺塔的规则一致。
resolve方法用来移动盘子,参数n表示要移动的盘子的数量,a是盘子所在的柱子,b是辅助柱子,c是目标柱子。注意此方法会首先检查参数n,当n为0时直接返回,这就是前面所说的“预定值”。如果没有对预定值的判断,resolve的递归过程将不会自然终止,而是无限进行下去,直到塞满系统内存堆栈而导致程序奔溃。
另外要注意的是程序将盘子的初始数量设为32个,你可以修改该值,但建议不要设置的过大,原因正如前面所计算的那样,如果采用64个圆盘,你将至少需要数百年才能看到结果(更可能的结果是由于步数太多,系统没有足够的内存而导致程序奔溃)。
import java.util.Iterator; import java.util.Stack; //Stack实例来保存每个柱子上的盘子及它们的顺序,Stack的先进先出的顺序 public class Hanio{ //输出移动的盘子 public static void print(Stack<Integer> s) { Iterator<Integer> i = s.iterator(); while (i.hasNext()) { System.out.printf("%d ", i.next()); } System.out.println(); } public static void resolve(int n, Stack<Integer> a, Stack<Integer> b, Stack<Integer> c) { if (n==0) return; resolve(n-1, a, c, b);//移动盘子,a移动到b,辅助B c.push(a.pop()); resolve(n-1, b, a, c);//移动盘子,b移动到c,辅助a } public static void main(String[] args) { int count = 3;//总的砝码的重量 Stack<Integer> a = new Stack<Integer>(); Stack<Integer> b = new Stack<Integer>(); Stack<Integer> c = new Stack<Integer>(); for (int i=count; i>0; i--) { a.push(i); } print(a); long start = System.currentTimeMillis(); resolve(count, a, b, c); long end = System.currentTimeMillis(); print(c); System.out.println((end - start)/1000); } }
相关文章推荐
- java构建树,构建tree,组装树结构,通用算法,用到递归算法
- 用java实现的经典递归算法
- java实现的经典递归算法三例
- overview_java(十)-递归算法
- 递归算法解决因式分解(java版)
- 分解质因素的Java递归算法
- 字符串子序列穷举(Java语言,递归算法)
- Java源码集合类TreeMap学习1——数据结构4平衡二叉树插入一个元素的递归算法
- 数据结构JAVA---递归算法
- Java 递归算法
- Java递归算法
- Java的递归算法
- Java 递归算法解迷宫问题
- Java递归算法构造JSON树形结构
- 递归算法总结java版
- Java-递归算法思想
- 使用递归算法结合数据库解析成java树形结构
- 原始的汉诺塔问题递归算法(java代码)
- [置顶] 用递归算法得到Java的树形结构
- 【递归算法】Java模拟汉诺塔移位、阶乘、斐波那契数列操作