递归的代码简洁性是大家公认的,极少的代码却可以完成同样功能的问题。但是我们都知道,追求代码简洁的同时,牺牲了更多的是时间问题。到底是递归效率比常规的迭代慢了多少?下面我们通过代码来看一下。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FibonacciDemo
{
class Program
{
//递归
static long fibonacci_recursion(int n) {
if (n <= 2) {
return 1;
}
return fibonacci_recursion(n - 1) + fibonacci_recursion(n - 2);
}
//常规的迭代
static long fibonacci_iteration(int n) {
long result;
long previous_result;
long next_older_result;
result = previous_result = 1;
while (n > 2) {
n--;
next_older_result = previous_result;
previous_result = result;
result = previous_result + next_older_result;
}
return result;
}
static void Main(string[] args)
{
//在运行前获取一下系统时间
DateTime beforDT = System.DateTime.Now;
fibonacci_recursion(45);
//在运行前后获取一下系统时间
DateTime afterDT = System.DateTime.Now;
//计算前后的时间差
TimeSpan ts = afterDT.Subtract(beforDT);
Console.WriteLine(ts.TotalMilliseconds);
DateTime beforDT1 = System.DateTime.Now;
fibonacci_iteration(45);
DateTime afterDT1 = System.DateTime.Now;
TimeSpan ts1 = afterDT1.Subtract(beforDT1);
Console.WriteLine(ts1.TotalMilliseconds);
Console.ReadLine();
}
}
}
当我们输入的数字是25的时候
结果是:
我们通过结果是看不出来递归和迭代有什么差异的
当我们输入的数字是30的时候
结果是:
我们通过看到这时候递归用了20毫秒,迭代竟然是0毫秒
当我们输入的数字是45的时候
在这里我插一句,运行时候,千万不要以为是电脑卡了,时间有点长
结果是
我们通过结果看到这时候递归用了32735毫秒,也就是32.735秒
迭代竟然是0.
我们简答的分析一下,其实我们知道,递归就是自己调用自己,自己本身就是一个函数,函数调用时要压如函数栈的。那么fibonacci_recursion(4)到底压入栈几次呢?如果是fibonacci_recursion(8)呢?
fibonacci_recursion(4)
= fibonacci_recursion(3)+fibonacci_recursion(2)
=fibonacci_recursion(2)+fibonacci_recursion(1)+fibonacci_recursion(2)=3
fibonacci_recursion(8)
= fibonacci_recursion(7) + fibonacci_recursion(6)
=fibonacci_recursion(6)+fibonacci_recursion(5)+fibonacci_recursion(5) +fibonacci_recursion(4)
=fibonacci_recursion(5) +fibonacci_recursion(4) +fibonacci_recursion(3) +fibonacci_recursion(2) +fibonacci_recursion(3)+fibonacci_recursion(2)
+fibonacci_recursion(3) +fibonacci_recursion(2) =fibonacci_recursion(4) +fibonacci_recursion(3)+fibonacci_recursion(3) +fibonacci_recursion(2)+fibonacci_recursion(3) +fibonacci_recursion(2) +fibonacci_recursion(3)+fibonacci_recursion(2)
+fibonacci_recursion(3) +fibonacci_recursion(2) =21
通过这么长的计算式子,我们可以看到,每一个函数都会触发两个相邻的函数,触发的两个函数还会触发4个,呈指数增长,因此,在数量比较多的时候要比迭代效率低很多。