1.学习目标

递归函数是直接调用自己或通过一系列语句间接调用自己的函数。递归在程序设计有着举足轻重的作用,在很多情况下,借助递归可以优雅的解决问题。本节主要介绍递归的基本概念以及如何构建递归程序。

通过本节学习,应掌握以下内容:

理解递归的基本概念,了解递归背后蕴含的编程思想

掌握构建递归程序的方法

2.递归

2.1递归的基本概念

递归是一种解决问题的方法,它将问题不断的分为更小的子问题,通过处理普通的子问题来解决问题。递归函数是直接调用自己或通过一系列语句间接调用自己的函数。需要注意的是,递归函数每次调用自己时,都会将原问题进行简化,最终较小问题的序列必须收敛于基本情况,解决问题,终止递归。利用递归可以非常优雅的解决一些复杂问题。很多数学函数就是递归定义的,比如使用递归定义的阶乘函数:

尽管这个定义是递归的,但它不是无限循环无法终止的。事实上,利用此函数可以非常简单的计算阶乘。例如计算3!,根据定义,有3!=3(3–1)!=3(2!),接下来我们需要解决2!,再次应用定义 3! = 4(2!) = 3[(2)(2−1)!] = 3(2)(1!),继续此过程,最后我们需要计算0!,而根据定义0!=1,计算过程就结束了:

3!=3(2!)=3(2)(1!)=3(2)(1)(0!)=3(2)(1)(1)=6

可以看到,递归定义并非是无限循环的,因为每次应用定义,程序都会将问题分解为更简单的子问题,在阶乘函数示例中,即为计算较小数的阶乘,直到计算0!,这不需要再次应用递归即可求解。当递归到底时,我们得到一个可以直接计算的闭合表达式,也被称为递归的“基本情况”。而函数调用自身来执行子任务时,被称为“递归情况”。

2.2递归的重要性

递归函数是从数学中借鉴的一种重要的编程技术,通常使用递归可以极大的降低代码量,在许多可以分解为子问题的任务中非常有用,例如,排序、遍历和搜索等通常可以借助递归方法快速的给出解决方案。

2.3递归三原则

和许多算法一样,递归同样有着需要遵守的重要原则,称为递归三原则:

  • 递归算法必须有基本情况
  • 递归算法必须改变状态并逐渐收敛于基本情况
  • 递归算法必须包含递归情况,能够递归的调用自身

需要注意的是,递归的核心思想并不是循环,而是将问题分解成更小、更容易解决的子问题。

2.4递归的应用

递归在程序设计中有着十分重要的作用,以下是一些常用到递归的实际场景:

  • 斐波那契数列、阶乘计算等数学问题
  • 归并排序、快速排序
  • 二分查找
  • 树和图的遍历以及相关问题
  • 汉诺塔

3.递归示例

本节中,我们将从简单的列表求和问题入手,了解递归算法的使用方式,然后再了解如何解决经典递归问题——汉诺塔。

3.1列表求和

列表求和是十分简单的问题,用来了解递归算法的思想再合适不过了。例如我们需要计算列表 [1, 2, 3, 4, 5] 的和,如果利用循环函数计算,则可以编写如下代码计算列表中所有数之和:

def sum_list(list_data):
    result = 0
    for i in range(list_data):
        result  = i
    return result

如果不使用循环,我们该如何解决这一问题呢?我们可以写出求和过程((((1 2) 3) 4) 5),而根据加法交换律,计算过程也可以写为(1 (2 (3 (4 5)))),这时我们就可以很清楚的看到,列表的数据总和等于列表第一个元素加上其余元素:

使用 python 实现以上等式如下:

def sum_list(list_data):
    if len(num_list) == 1:
        return list_data[0]
    else:
        return list_data[0]   sum_list(list_data[1:])

在代码中,首先给出了函数退出的条件,这就是递归函数的基本情况,在示例中就是说,长度为 1 的列表,其元素和就是列表中的数。不满足退出条件,sum_list 则会调用自己,这就是递归函数的递归情况,也是其称为递归函数的原因。

在下图(a)中,可以看到求解 [1, 2, 3, 4, 5] 时的递归调用过程,每次递归调用都是在解决一个更接近基本情况的问题,直到问题不能被进一步简化。

当问题无法简化时,开始拼接所有子问题的解,下图(b)展示递归函数 sum_list 在返回一系列调用结果时所进行的加法操作,当返回到顶层时,就解决了最初的问题。

3.2汉诺塔(Towers of Hanoi)问题

汉诺塔(Towers of Hanoi)是一道十分经典的谜题。它由三个塔和许多不同尺寸的圆盘组成,这些圆盘可以移动到任何杆上。开始时圆盘按尺寸升序排列在一个塔上,顶部的圆盘最小,底部圆盘最大。谜题的目标是将叠好的圆盘移动到另一个杆,且满足以下规则:

  • 一次只能移动一个圆盘
  • 较大圆盘不能放在较小的圆盘上

接下来我们讲解如何借助一根中间塔 Auxiliary,将高度为 n 的一叠圆盘从起始塔 Source 移到终点塔 Destination:

  • 借助终点塔 Destination,将顶部的 n - 1 个圆盘从 Source 移动到 Auxiliary
  • 将第 n 个圆盘从 Source 塔移动到终点塔 Destination
  • 借助 Source 塔,将 n - 1 个磁盘从辅助塔 Auxiliary 移动到终点塔 Destination

只要遵循汉诺塔的移动规则,就可以递归地执行上述步骤。最简单的汉诺塔是只有一个盘子,在这种情况下,只需将这个盘子移到终点柱子 Destination 即可,这就是基本情况。上述递归步骤通过逐渐减小高度 n 来向基本情况靠近,如下图所示:

算法的关键在于进行两次递归调用,第一次递归是将除了最后一个圆盘以外的其他所有圆盘从 Source 塔移到辅助塔 Auxiliary 。然后将最后一个圆盘移到终点塔 Destination。第二次递归是将圆盘从 Auxiliary 移到 Destination:

def towersOfHanoi(number, source=1, destination=3, auxiliary=2):
    if number >= 1:
        towersOfHanoi (number - 1, source, auxiliary, destination)
        print("Move disk %d from tower %d to tower %d" % (number, source, destination))
        towersOfHanoi (number - 1, auxiliary, destination, source)
towersOfHanoi(number=3)

程序输出如下所示:

Move disk 1 from tower 1 to tower 3
Move disk 2 from tower 1 to tower 2
Move disk 1 from tower 3 to tower 2
Move disk 3 from tower 1 to tower 3
Move disk 1 from tower 2 to tower 1
Move disk 2 from tower 2 to tower 3
Move disk 1 from tower 1 to tower 3

以上就是Python数据结构之递归方法详解的详细内容,更多关于Python 数据结构递归的资料请关注Devmax其它相关文章!

Python数据结构之递归方法详解的更多相关文章

  1. XCode 3.2 Ruby和Python模板

    在xcode3.2下,我的ObjectiveCPython/Ruby项目仍然可以打开更新和编译,但是你无法创建新项目.鉴于xcode3.2中缺少ruby和python的所有痕迹(即创建项目并添加新的ruby/python文件),是否有一种简单的方法可以再次安装模板?我发现了一些关于将它们复制到某个文件夹的信息,但我似乎无法让它工作,我怀疑文件夹的位置已经改变为3.2.解决方法3.2中的应用程序模板

  2. ios – 嵌套递归函数

    我试图做一个嵌套递归函数,但是当我编译时,编译器崩溃.这是我的代码:编译器记录arehere解决方法有趣的…它似乎也许在尝试在定义之前捕获到内部的引用时,它是bailing?以下修复它为我们:当然没有嵌套,我们根本没有任何问题,例如以下工作完全如预期:我会说:报告!

  3. swift override --有一个递归问题未解决

    classca{varcount:Int{get{return1;}set{self.count=newValue;}}funcdescribe()->String{return"ca";}}classcb:ca{overridefuncdescribe()->String{return"cb";}overridevarcount:Int{get{return2;}set{//引起了递归调用,未找

  4. swift篇第一期:简单的数据结构

    首先我们可以去使用Playground来编码,并且会实时的显示对应的编码信息,这样我们就不用每次都去运行程序来显示输出的东西了哦,也方便了我们对某些语句的验证,这个是比较赞的var与let前者为可变修饰符,后者为不可变从字面意思我们就可以很好的区分了常用的类型呢,跟其他语言基本相同啦,主要有几种:1.int类型2.Float,Double类型3.String类型4.Boolean类型当我们去声明一

  5. Swift基本使用-函数和闭包(三)

    声明函数和其他脚本语言有相似的地方,比较明显的地方是声明函数的关键字swift也出现了Python中的组元,可以通过一个组元返回多个值。传递可变参数,函数以数组的形式获取参数swift中函数可以嵌套,被嵌套的函数可以访问外部函数的变量。可以通过函数的潜逃来重构过长或者太复杂的函数。

  6. Swift2.0语言教程之函数嵌套调用形式

    Swift2.0语言教程之函数嵌套调用形式Swift2.0语言函数嵌套调用形式在Swift中,在函数中还可以调用函数,从而形成嵌套调用。以下将对这两种调用进行详细讲解。调用方式如图7.4所示。图7.4函数嵌套的形式以下将使用函数的嵌套调用实现对s=22!这个数值,即调用f1()函数,计算22,结果为4,然后在调用f2()函数,对4的阶乘求取,计算完成22!但是在Swift语言中递归必须要有一个满足结束的条件。

  7. 【Swift】学习笔记(九)——枚举

    因为类完全可以替代枚举。不过swift中也有许多类的特性被枚举支持。这样判断必须穷举所有成员,否则就需要增加default这个选项了。使用递归枚举时,编译器会插入一个中间层。

  8. Swift实现的快速排序及sorted方法的对比

    Swift语言有着优秀的函数式编程能力,面试的时候面试官都喜欢问我们快速排序,那么用Swift如何实现一个快速排序呢?然后实现快速排序的方法:可以发现使用Swift实现快速排序的代码非常的简洁。在看完这段代码后我做了如下思考:既然是排序,那么必然可以使用系统的sorted方法,效果如何呢?对于快排最头疼的顺序性数组,sorted的重复次数只有n次!说明在面对这种类型的数组的时候sorted方法进行过判断,直接输出了。

  9. Swift 集合数据结构性能分析

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  10. Swift中的集合类数据结构

    在那种情况下,你将会需要一种基本的集合类数据结构。继续学习,你将会比较成熟的Cocoa数据结构与对应的纯Swift结构的性能。常见iOS数据结构iOS中三种最常用的数据结构是arrays,dictionaries和sets。除了在Swift和Objective-C中旧的Foundation框架中的数据结构,现在又有了新的仅支持Swift版本的数据结构与语言紧密结合在一起。Swift数组是同质的,意味着每一个Swift数组都只包含一种类型的对象。

随机推荐

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. python数学建模之三大模型与十大常用算法详情

    这篇文章主要介绍了python数学建模之三大模型与十大常用算法详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感想取得小伙伴可以参考一下

  3. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  4. 使用pyinstaller打包.exe文件的详细教程

    PyInstaller是一个跨平台的Python应用打包工具,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,下面这篇文章主要给大家介绍了关于使用pyinstaller打包.exe文件的相关资料,需要的朋友可以参考下

  5. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  6. Python list append方法之给列表追加元素

    这篇文章主要介绍了Python list append方法如何给列表追加元素,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. 利用python实现简单的情感分析实例教程

    商品评论挖掘、电影推荐、股市预测……情感分析大有用武之地,下面这篇文章主要给大家介绍了关于利用python实现简单的情感分析的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  10. Pycharm中运行程序在Python console中执行,不是直接Run问题

    这篇文章主要介绍了Pycharm中运行程序在Python console中执行,不是直接Run问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回
顶部