`
MouseLearnJava
  • 浏览: 466107 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

斐波那契数的递归与非递归实现

    博客分类:
  • Java
阅读更多
斐波那契数计算的方法一般采用递归的方法,返回类型一般采用int或者long类型。在这种条件下会产生两个问题:
1. 效率问题,比如计算第46个斐波那契数值,需要6秒多。计算第50个斐波那契数需要一分钟左右,后面越来越难以想象。
2. 数值溢出问题。返回类型采用int类型的话,最多可以计算出f(46) = 1836311903, 计算f(47)时就会产生溢出。返回类型采用long类型的话,最多可以计算出f(92) = 7540113804746346429, 计算f(93)时就会产生溢出。

解决效率问题的方法就是采用非递归的方式。
非递归的思想 当n =1 或者 n=2的时返回1。当n大于2时,通过for循环改变值来实现。
如:初始化两个变量num1 = 1, num2 =1,把它们想象成f(1) 和 f(2),在循环体中改变它们对应的值。把num2的值表示成num1, num2的值用num1与num2的和来表示。这样一来, num2就是f(n)的结果。



非递归实现比较快,一般在0.0秒级。

解决数值溢出的方法是采用BigInteger来实现。

f(500) = 139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125

Time Elasped:0.0秒

递归与非递归的代码如下:
import java.math.BigInteger;

public class Fibonacci {

	/**
	 * 
	 * 采用递归方法实现
	 * 
	 * 用int类型的话,最多可以计算出f(46) = 1836311903, 计算f(47)时就会产生溢出。
	 * f(42) = 267914296
	 * f(43) = 433494437
	 * f(44) = 701408733
	 * f(45) = 1134903170
	 * f(46) = 1836311903
	 * f(47) = -1323752223
	 * 

	 * 
	 * @return 返回第n个斐波纳契数
	 */
	public int fibonacci1(int n) {
		if (1 == n || 2 == n) {
			return 1;
		} else {
			return fibonacci1(n - 1) + fibonacci1(n - 2);
		}
	}

	/**
	 * 
	 * 采用非递归方法实现,效率比递归方法要高很多。
	 * 
	 * 用int类型的话,最多可以计算出f(46) = 1836311903, 计算f(47)时就会产生溢出。
	 * f(42) = 267914296
	 * f(43) = 433494437
	 * f(44) = 701408733
	 * f(45) = 1134903170
	 * f(46) = 1836311903
	 * f(47) = -1323752223
	 * 

	 * 
	 * @return 返回第n个斐波纳契数
	 */
	public int fibonacci2(int n) {
		if (1 == n || 2 == n) {
			return 1;
		}
		int num1 = 1;
		int num2 = 1;
		int temp = 0;
		for (int i = 2; i < n; i++) {
			temp = num2;
			num2 += num1;
			num1 = temp;
		}
		return num2;
	}

	/**
	 * 
	 * 采用递归方法实现
	 * 
	 * 用long类型的话,最多可以计算出f(92) = 7540113804746346429, 计算f(93)时就会产生溢出。
	 * f(90) = 2880067194370816120
	 * f(91) = 4660046610375530309
	 * f(92) = 7540113804746346429
	 * f(93) = -6246583658587674878
	 * 

	 * 
	 * @return 返回第n个斐波纳契数
	 */
	public long fibonacci3(int n) {
		if (1 == n || 2 == n) {
			return 1;
		} else {
			return fibonacci3(n - 1) + fibonacci3(n - 2);
		}
	}

	/**
	 * 
	 * 采用非递归方法实现,效率比递归方法要高很多。
	 * 
	 * 用long类型的话,最多可以计算出f(92) = 7540113804746346429, 计算f(93)时就会产生溢出。
	 * f(90) = 2880067194370816120
	 * f(91) = 4660046610375530309
	 * f(92) = 7540113804746346429
	 * f(93) = -6246583658587674878
	 * 

	 * 
	 * @return 返回第n个斐波纳契数
	 */
	public long fibonacci4(int n) {
		if (1 == n || 2 == n) {
			return 1;
		}
		long num1 = 1;
		long num2 = 1;
		long temp = 0;
		for (int i = 2; i < n; i++) {
			temp = num2;
			num2 += num1;
			num1 = temp;
		}
		return num2;
	}
	
	/**
	 * 
	 * 采用非递归的方式来实现,同时采用BigInteger来实现。
	 * 
	 * 

	 * @return 返回第n个斐波纳契数
	 */
	public BigInteger populateWithoutRecursion(int n){
		if (1 == n || 2 == n) {
			return new BigInteger("1");
		}
		BigInteger num1 = new BigInteger("1");
		BigInteger num2 = new BigInteger("1");
		BigInteger temp = new BigInteger("0");
		for(int i=2;i<n;i++){
			temp = num2;
			num2 = num2.add(num1);
			num1 = temp;
		}
		return num2;
	}
	
	public static void main(String[] args) {
		Fibonacci f = new Fibonacci();
		long start = System.currentTimeMillis();
		System.out.println( f.populateWithoutRecursion(500));
		long end = System.currentTimeMillis();
		System.out.println("Time Elasped:" + (end - start)/1000.0 + "秒");
	}
	
	
}

  • 大小: 68.1 KB
2
1
分享到:
评论
1 楼 zenghuiss 2015-07-24  
非递归时,要<=n才行哦

相关推荐

    Fibonacci递归与非递归实现

    Fibonacci数列的java实现,包括递归与非递归实现

    非递归实现fibonacci数列

    使用C++非递归实现fibonacci数列,对正在学习算法的同学应该挺有帮助的

    C++实现Fibonacci数列递归及非递归算法

    本文将探讨如何使用C++语言来实现Fibonacci数列的递归和非递归算法。 **递归算法** 递归是一种解决问题的方法,它定义一个函数或过程通过调用自身来解决问题。对于Fibonacci数列,递归实现非常直观: ```cpp int ...

    斐波那契递归时间和非递归时间的比较(csdn)————程序.pdf

    在主函数 `main()` 中,用户被要求输入要计算的斐波那契数的索引 `n` 和选择的算法(1 代表非递归,2 代表递归)。程序将打印出结果以及对应算法的运行时间。 总的来说,这个程序展示了如何使用 C 语言和时间测量...

    斐波那契非递归 C语言源码 大数加法

    这种非递归实现的优点在于它可以处理任意大的斐波那契数,只要内存足够存储。同时,由于没有递归调用,它的运行时间复杂度比递归版本更低,更适合大数运算。在实际编程中,为了提高效率,还可以考虑使用更高级的数据...

    Labview实现递归:斐波那契数列

    斐波那契数列: 在数学上它以递归的方式进行定义,指这样的一个数列:0、1、1、2、3、5、8、13、21、34、55、89、144……,即前两个数为分别为0和1...本例为LabVIEW中编写递归VI实现求解斐波那契数列Fib(n)中第n项的值

    菲波拉契数列的递归与非递归算法

    本篇文章将深入探讨斐波那契数列的递归与非递归算法实现方法,并通过具体的代码示例来帮助读者理解这两种方法的特点和适用场景。 #### 二、斐波那契数列定义 斐波那契数列是由以下递推公式定义的数列: \[ F(n) = ...

    Fibonacci数列(非递归的函数调用)

    斐波那契数列是一个经典的数学概念,在计算机科学...了解和实践非递归的斐波那契数列计算,对于提升C++编程技能和算法理解能力非常有帮助。在实际项目中,类似的方法也可以应用于其他需要高效计算序列或序列项的问题。

    组合数学fibonacci数列递归非递归求解

    ### Fibonacci数列的非递归求解方法 非递归方法避免了递归方法的重复计算问题,提高了计算效率。给定文件中的第二个示例展示了如何使用循环结构来求解Fibonacci数列: ```c #include void main() { int n; scanf...

    斐波那契数列(fibonacci)-java实现-非递归

    斐波那契数列(fibonacci)-java的非递归实现。

    JAVA递归与非递归实现斐波那契数列

    总之,斐波那契数列的递归与非递归实现是Java编程中值得深入学习的一个主题。理解这两种方法的原理以及它们在时间和空间复杂度上的差异,可以帮助我们更好地选择合适的数据结构和算法,优化程序性能。在面对实际问题...

    华为题(斐波那契数列非递归)[定义].pdf

    华为题(斐波那契数列非递归) ...结论:本文总结了斐波那契数列的定义、非递归实现、栈数据结构、malloc和realloc函数、斐波那契数列的应用和软件网络技术等知识点,并对斐波那契数列的实现和应用进行了深入探讨。

    c#斐波那契数列(Fibonacci)(递归,非递归)实现代码

    在C#中,斐波那契数列可以通过两种主要方法实现:递归和非递归(或迭代)。 1. **递归实现**: 递归实现是最直观的方法,它通过调用自身来计算数列中的下一个数字。在提供的代码中,`TopDownRecursion`函数就是递归...

    算法基础与递归-百积问题-递归求公约数-求阶乘-斐波那契数列

    * 通过递归和非递归方法实现最大公约数的计算 * 通过递归和非递归方法实现阶乘的计算 * 实现斐波那契数列的计算 * 实现汉诺塔问题的解决 四、代码实现 下面是实验的代码实现: 1. 汉诺塔问题的解决 ```c void ...

    Java实现用递归算法和非递归算法求解斐波那契数列问题.docx

    Java实现用递归算法和非递归算法求解斐波那契数列问题 斐波那契数列是一个经典的数学问题,指的是一个数列中的每个数都是其前两个数的和,通常这个数列以0和1开始,也就是说,斐波那契数列是指以下这样的一个数列:...

    java用非递归的方法打印Fibonacci数列

    Java 中的 Fibonacci 数列是通过非递归的方法来实现的,该方法使用循环来计算 Fibonacci 数列的每个元素,而不使用递归函数。 Java 中的 Fibonacci 数列的定义是从 0 开始的,第一个 Fibonacci 数是 0,第二个是 1...

    C预言fibonacci函数非递归版

    表达式C预言fibonacci函数非递归版

    递归算法到非递归算法的转换.ppt

    然而,在某些场景下,非递归算法可能更有利于性能优化或理解。本章将探讨如何将递归算法转换为非递归算法。 首先,我们要了解递归的定义。递归发生在一个过程或函数在定义中调用自身,这被称为直接递归。如果一个...

Global site tag (gtag.js) - Google Analytics