数据结构与算法(二)——递归算法

书读的越多而不加思考,你就会觉得你知道得很多;而当你读书而思考得越多的时候,你就会越清楚地看到,你知道得很少。

导读:本篇文章讲解 数据结构与算法(二)——递归算法,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

目录

前言

递归算法

1、什么是递归算法

2、核心理念

3、代码演示

4、问题探讨:只递不归会怎样?

5、小结

递归实例:汉诺塔问题

1、故事引入

2、移动盘子的逻辑

3、N个盘子的移动分析

4、代码实现N个盘子的移动

5、汉诺塔移动次数计算公式


前言

本文是我关于递归算法的学习记录,完成这篇博客花了大半天的时间,自认为图文结合表述的还算详细,也希望大家阅读后会感到有所帮助;

这篇博客有一些细节的地方完善的不是很好,我日后有更加清晰理解的时候会再优化这篇博客,如果读者有什么不理解的地方,欢迎评论区留言;有写的不对的地方,欢迎批评指正,希望能够完善这篇博客。

递归算法

1、什么是递归算法

定义一个函数,在函数里面调用函数,并且要有结束条件

2、核心理念

例如:从前有座山,山上有座庙,庙里有个老和尚和小和尚将故事,故事是从前有座山…

递归的核心理念就是函数调用函数,就像故事里面有故事

但是,这个故事并不算一个递归,因为故事只有递(调用自身),没有归(结束条件

3、代码演示

def f(x):
    return x + f(x-1)

print(f(3))

数据结构与算法(二)——递归算法

函数每次都会无条件的调用自己,为了解决这个问题,我们需要在函数中加入一个判断语句,以决定何时停止调用自己;

以参数大于0为停止条件:

def f(x):
    if x > 0:
        return x + f(x-1)
    else:
        return 0

程序的运行结果是:

数据结构与算法(二)——递归算法

4、问题探讨:只递不归会怎样?

def f(x):
    return x + f(x-1)

print(f(3))

运行上面只递不归的函数,程序会报错;

为什么会这样呢?

在程序运行的时候,调用函数是有代价的,会占用一片叫做栈(stack)的内存空间,调用函数时,必须要放一些数据到栈里面,当函数运行结束时,这些数据会从栈里被取出

 数据结构与算法(二)——递归算法

但是,如果调用了很多函数,这些函数都不返回的话,栈就被塞满了(函数调用时往栈里面存数据,函数结束时从栈里面取出数据),数据没有地方放了,这种情况叫做栈溢出错误;对于程序运行而言,这是致命的错误,因此程序会被操作系统强行终止

数据结构与算法(二)——递归算法

在Python中,可以人为设置递归调用的次数(深度),尽量保证程序不会崩溃。

5、小结

  • 递归:函数自己调用自己
  • 只递不归会导致程序崩溃
  • 要在适当的时候终止递归(加if条件判断语句)

递归实例:汉诺塔问题

1、故事引入

一个印度传说。

大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上,从下往上按照大小顺序摞着64片黄金圆盘。

大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。

在小圆盘上不能放大圆盘在三根柱子之间一次只能移动一个圆盘

64根柱子移动完毕之日,就是世界毁灭之时。

数据结构与算法(二)——递归算法

2、移动盘子的逻辑

假设盘子数目为n,n=3时,如果想把A中盘子全部移到C盘上

数据结构与算法(二)——递归算法

假设三个盘子分别为小、中、大,我们需要这样移动(注意要符合移动圆盘的要求):

小->C,中->B,小->B,大->C,小->A,中->C,小->C;共计七步。

数据结构与算法(二)——递归算法

3、N个盘子的移动分析

以上述移动盘子的逻辑为例,不能推测出,移动N(N>2)个盘子时,需要下面这几步骤:

  1. 把n-1个圆盘从A经过C移动到B;
  2. 把第n个圆盘从A移动到C;
  3. 把n-1个小圆盘从B经过A移动到C。

4、代码实现N个盘子的移动

def hanoi(n,a,b,c):
    """
    n表示圆盘数
    a表示第一根柱子最上面的圆盘(圆盘的起始位置)
    b表示第二根柱子最上面的圆盘(想将所有圆盘从a移动到c需要借助的柱子)
    c表示第三根柱子最上面的圆盘(圆盘的目标位置)
    """
    if n>0:
        hanoi(n-1,a,c,b)    # 步骤一:把n-1个圆盘从A经过C移动到B;
        print("moving from %s to %s." % (a,c))    # 步骤二:把第n个圆盘从A移动到C;
        hanoi(n-1,b,a,c)    # 步骤三:把n-1个小圆盘从B经过A移动到C。



# 测试圆盘数为1、2、3时,我们的移动步骤
hanoi(1,'A','B','C')
print('------------')
hanoi(2,'A','B','C')
print('------------')
hanoi(3,'A','B','C')

我们尝试打印出圆盘数分别为1、2、3时,需要移动的步骤,控制台打印结果为:

 数据结构与算法(二)——递归算法

 

5、汉诺塔移动次数计算公式

设圆盘数为n时,移动次数为f(n)

根据N个盘子的移动分析步骤可以得知,第一步要移动f(n-1)次,第二步要移动1次,第三步要移动f(n-1)次

所以,汉诺塔移动次数计算公式

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

由上图打印结果可以知道,f(1)=1;f(2)=3;f(3)=7,可以带入计算公式检验一下,的确是符合的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/122878.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!