JS汉诺塔、Fibonacci 、青蛙跳台阶

函数直接或间接调用自身

避免无限递归,无限递归导致执行栈溢出

对比死循环不会导致栈溢出

执行栈

任何代码的执行都必须有一个执行环境,执行环境为代码的执行提供支持

执行环境是放到执行栈中的

每个函数的调用,都需要创建一个函数的执行环境,函数调用结束,执行环境销毁

执行栈有相对谷固定的大小,如果执行环境太多,执行栈无法容纳,栈溢出会报错

尾递归

如果一个函数最后一条语句是调用函数,并且调用函数不是表达式的一部分,则该语句称为尾调用,如果尾调用是调用自身函数,称为尾递归

某些语言或执行环境会对尾调用进行优化,他们会销毁当前函数,避免执行栈空间被调用

浏览器执行环境中,尾调用没有优化

nodeJs中有优化

1.汉诺塔

解析参考这个链接吧

C语言实现汉诺塔【图文讲解】_汉诺塔c语言-CSDN博客

// hannuo塔
function move (pillarStart, pillarEnd, plateNumer) {
    console.log(`把第${plateNumer}个盘子从${pillarStart}号柱子挪到${pillarEnd}号柱子`)
}
// no1, no2, no3三个编号的柱子
// 盘子数量
function movePlate (no1, no2, no3, plateNumer) {
    if (plateNumer == 1) {
        move(no1, no3, plateNumer)
    } else {
        //n-1从1号挪到2号 需经过3号
        movePlate(no1, no3, no2, plateNumer - 1)
        //n挪到3号
        move(no1, no3, plateNumer)
        //n-1从2号挪到3号,需经过1号
        movePlate(no2, no1, no3, plateNumer - 1)
    }
}

movePlate('A', 'B', 'C', 4)

2.Fibonacci 

使用第二种 递归的方式更为简洁 

//动态规划 0,1,1,2,3,5,8,13,······
function fibo (n) {
    if (n <= 0) return -1
    if (n == 1) return 0
    if (n == 2) return 1
    var a = 0
    var b = 1
    var c = 0
    for (var i = 3; i <= n; i++) {
        c = a + b
        a = b
        b = c
    }
    return c
}
console.log(fibo(3))
// f(n) = f(n - 1) + f(n - 2) 递归
function FIBO (n) {
    if (n <= 0) return -1
    if (n == 1) return 0
    if (n == 2) return 1
    return FIBO(n - 1) + FIBO(n - 2)
}
console.log(FIBO(5))

3.青蛙跳台阶

一个青蛙,一次只能跳一级合阶,或者跳两级合阶。
问:这个青蛙跳上n级台阶有多少种跳法。
如果这只青蛙,跳上了第n级台阶,那么最后二次跳跃之前,他一定在n-1级台阶或n-2级台阶上。
那么跳上n级台阶有多少种情况就变成了两个子问题:跳上n-1级台阶的跳法 加上 跳上n-2级台阶的跳法。
按照此逻辑递推,跳上n-1级台阶可以拆解为两公子问题既:跳上n-2级台阶的跳法 加上 跳上n-3级台阶的跳法

f(n) = f(n - 1) + f(n - 2)

function jump (n) {
    if (n <= 0) return -1
    if (n == 1) return 1
    if (n == 2) return 2
    return jump(n - 1) + jump(n - 2)
}
console.log(jump(5))//8

4.变态青蛙跳台阶

这只青蛙 一次可以跳1级台阶、2级台阶、或n级台阶

问:这只青蛙 跳上n级台阶共有多少种方法

f(n) = f(n - 1) + f(n - 2) + f(n - 3) +·····+f(2) + f(1) + f(0)

function jump (n) {
    if (n <= 0) return -1
    if (n == 1) return 1
    if (n == 2) return 2
    var result = 0
    for (var i = 1; i < n; i++) {
        result += jump(n - i)
    }
    return result + 1//+1代表从0级台阶直接跳上去的情况
}
console.log(jump(5))//16

 

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值