JavaScript数据结构之 —— 11动态规划(实例)

递归

递归是一种解决问题的方法,通常涉及函数调用自身。我们使用递归,并不是因为它运行速度更快,而是因为它更利于理解,代码也少。

能够像下面这样直接调用自身的方法或函数,是递归函数:

var recursiveFunction = function(someParam){
   
	recursiveFunction(someParam);
};

能够像下面这样间接调用自身的函数,也是递归函数:

var recursiveFunction1 = function(someParam){
   
	recursiveFunction2(someParam);
};
var recursiveFunction2 = function(someParam){
   
	recursiveFunction1(someParam);
};

栈溢出错误

递归并不会无限地执行下去;浏览器会抛出错误,也就是所谓的栈溢出错误(stack overflow error)
每个浏览器都有自己的上限,可用以下代码测试:

var i = 0;
function recursiveFn () {
   
	i++;
	recursiveFn();
}
try {
   
	recursiveFn();
} catch (ex) {
   
	console.log('i = ' + i + ' error: ' + ex);
}

在这里插入图片描述

计算斐波那契数列

递归方法

n = (n-1) + (n-2)
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …

function fibonacci(num){
   
	if (num < 2) {
   
		return num;
	}
	return fibonacci(num - 1) + fibonacci(num - 2);
}

上面这个函数的问题在于它的执行效率非常低,有太多的值在递归调用中被重新计算,如果编译器可以将已经计算的值记录下来,函数的执行效率就不会如此差。我们可以使用动态规划的技巧来设计一个效率更高的算法。

假如需要找出第六个位置的斐波那契数,如下所示,仅仅是第三个斐波那契数就计算了三次,求值越大,计算的次数会变得更多:
在这里插入图片描述

动态规划

使用递归去解决问题虽然简洁,但效率不高,尽管写出来的程序简洁,但是执行效率低下。许多使用递归去解决的编程问题,可以重写为使用动态规划的技巧去解决。动态规划方案通常会使用一个数组来建立一张表,用于存放计算过程中的值,可以避免重新计算。

function dynFib(n) {
   
	if (n < 2) {
   
		return n;
	}
	else {
   
		var val = [0,1]; // 初始化 作为保存中间结果的数组
		for (var i = 2; i <= n; ++i) {
   
			val[i] = val[i-1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值