借汉诺塔理解栈与递归

我们先说,在一个函数中,调用另一个函数。

首先,要意识到,函数中的代码和平常所写代码一样,也都是要执行完的,只有执行完代码,或者遇到return,才会停止。

那么,我们在函数中调用函数,执行完了,就会重新回到本函数中,继续向下执行,直到结束。

在执行其它函数时,本函数相当于中断了,不执行了。那我们重新回来的时候,要从刚才暂停的地方开始,继续执行,这期间,所有现场信息都要原封不动,就相当于时间暂停了一样,什么都不能改变,这样才能做到程序的准确。

所以,通常,在执行另一个函数之前,电脑会将现场信息压入一个系统栈,为被调用的函数分配存储区,然后开始执行被调函数。执行完毕后,保存计算结果,释放被调函数的空间,按照被调函数里保存的返回地址,返回到原函数。

那什么是递归函数呢?

就是多个函数嵌套调用。不同的是,这些函数是同一个函数,只是参数可能不同,甚至参数也一样,只是存储空间不同。

每一层递归所需信息构成一个栈,每一块内存储着所有实在参数,所有局部变量,上一层的返回地址,等等一切现场信息。每执行完就弹出。

递归函数有着广泛应用,主要适合可以把自身分化成一样的子问题的问题。比如汉诺塔。

 

汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

思路:函数(n,a,b,c)含义是把n个盘子从a柱子搬到c柱子的方法

一个盘子,直接搬过去。

多个盘子,我们把n-1个盘子都移动到另一个柱子上,把最大的搬过去然后把剩下的搬过去。

 

def hanoi(n, a, b, c):if n == 1:print(a, '-->', c)else:hanoi(n - 1, a, c, b)print(a, '-->', c)hanoi(n - 1, b, a, c)
# 调用
hanoi(3, 'A', 'B', 'C')

结果:

A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C

我们的栈:

第一次:

我们把hanoi(3, 'A', 'B', 'C')存了起来,调用了hanoi(3-1, 'A', 'C', 'B'),现在栈里压入了3, 'A', 'B', 'C',还有函数执行到的位置等现场信息。然后执行hanoi(3-1, 'A', 'C', 'B'),发现要调用hanoi(3-1-1, 'A', 'B', 'C'),我们又把3-1, 'A', 'C', 'B'等信息压入了栈,现在栈是这样的:

栈头

2, 'A', 'C', 'B'

3, 'A', 'B', 'C'

栈尾

 

然后执行hanoi(3-1-1, 'A', 'B', 'C'),发现n=1了,打印了第一条A --> C,然后释放掉了hanoi(3-1-1, 'A', 'B', 'C')的空间,并通过记录的返址回到了hanoi(3-1, 'A', 'C', 'B'),然后执行打印语句A --> B,然后发现要调用hanoi(3-1-1, 'C', 'A', 'B'),此时栈又成了:

2, 'A', 'C', 'B'
3, 'A', 'B', 'C'

调用hanoi(1, 'A', 'C', 'B')发现可以直接打印,C --> B。

然后我们又回到了2, 'A', 'C', 'B'这里。发现整个函数执行完了,那就弹出吧。这时栈是这样的:

3, 'A', 'B', 'C'

只有这一个。

我们继续执行这个函数的代码,发现

def hanoi(n, a, b, c):
    if n == 1:
        print(a, '-->', c)
    else:
        hanoi(n - 1, a, c, b)//执行到了这里
        print(a, '-->', c)
        hanoi(n - 1, b, a, c)

 

那我们就继续执行,发现要打印A --> C

然后继续,发现要调用        hanoi(n - 1, b, a, c),那我们继续把现场信息压栈,继续执行就好了。

 

递归就是把大问题分解成小问题进而求解。

具体执行就是通过系统的栈来实现返回原函数的功能。

 

多色汉诺塔问题:

 

奇数号圆盘着蓝色,偶数号圆盘着红色,如图所示。现要求将塔座A 上的这一叠圆盘移到塔座B 上,并仍按同样顺序叠置。在移动圆盘时应遵守以下移动规则:

规则(1):每次只能移动1 个圆盘;
规则(2):任何时刻都不允许将较大的圆盘压在较小的圆盘之上;
规则(3):任何时刻都不允许将同色圆盘叠在一起;
 

其实双色的汉诺塔就是和无色的汉诺塔算法类似,通过推理可知,无色汉诺塔的移动规则在双色汉诺塔这里的移动规则并没有违反。

这里说明第一种就可以了:Hanoi(n-1,A,C,B);

在移动过程中,塔座上的最低圆盘的编号与n-1具有相同奇偶性,塔座b上的最低圆盘的编号与n-1具有不相同的奇偶性,从而塔座上的最低圆盘的编号与n具有相同的奇偶性,塔座上c最低圆盘的编号与n具有不同的奇偶性;
 

所以把打印操作换成两个打印即可

 

总:因为递归可能会有重复子问题的出现。

就算写的很好,无重复子问题,也会因为来回调用、返回函数,而速度较慢。所以,有能力的可以改为迭代或动态规划等方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445538.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qt超强绘图控件qwt - 安装及配置

qwt是一个基于LGPL版权协议的开源项目, 可生成各种统计图。它为具有技术专业背景的程序提供GUI组件和一组实用类,其目标是以基于2D方式的窗体部件来显示数据, 数据源以数值,数组或一组浮点数等方式提供, 输出方式可以是…

BFPRT

在一大堆数中求其前k大或前k小的问题,简称TOP-K问题。而目前解决TOP-K问题最有效的算法即是BFPRT算法,其又称为中位数的中位数算法,该算法由Blum、Floyd、Pratt、Rivest、Tarjan提出,最坏时间复杂度为O(n)O(n)。 读者要会快速排序…

HistCite 的使用方法

摘要 读文献自然要读精品,在面对一个陌生领域,如何才能以最快速度定位精品文献呢?本文将详细介绍 HistCite 的使用方法,结合 Web of Science 和 Endnote ,演示如何在几个小时之内,对某个陌生领域的文献进行…

数据结构课上笔记7

介绍栈和队列基本概念和用法。 设输入序列1、2、3、4,则下述序列中( )不可能是出栈序列。【中科院中国科技大学2005】 A. 1、2、3、4 B. 4、 3、2、1 C. 1、3、4、2 D.4、1、2、3 选…

ROC曲线与AUC值

ROC曲线与AUC值 1.概述AUC(Area Under roc Curve)是一种用来度量分类模型好坏的一个标准。这样的标准其实有很多,例如:大约10年前在machine learning文献中一统天下的标准:分类精度;在信息检索(IR)领域中常…

设置SSH免密码自动登录(使用别名)

每次登录服务器都要写一大串的用户名(username服务器地址)和登录密码十分的繁琐,所以本文就告诉大家如何通过修改配置文件,达到只需要输入:ssh jack(你起的别名)就可以一键登录到服务器中。 1.创建公钥(相当…

串的定长表示

思想和代码都不难&#xff0c;和线性表也差不多&#xff0c;串本来就是数据受限的线性表。 串连接&#xff1a; #include <stdio.h> #include <string.h> //串的定长顺序存储表示 #define MAXSTRLEN 255 //用户可在255以内定义最大串长 typedef unsigned cha…

轻松理解牛顿迭代法且用其求平方根

牛顿迭代法概述 牛顿迭代法&#xff08;Newton’s method&#xff09;又称为牛顿-拉弗森方法&#xff08;Newton-Raphson method&#xff09;&#xff0c;它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。 牛顿迭代公式 设rrr是f(x)0f(x)0f(x)0的根&#…

如何使用cookie信息,完成自动登录

在做爬虫任务的时候&#xff0c;我们常常会遇到很多网页必须登录后&#xff0c;才可以开放某些页面。所以登录是爬取网页的第一步。但是&#xff0c;通过post表单&#xff08;包含用户名和密码&#xff09;的方法&#xff0c;对于那些不需要输入比较复杂的验证码的网页&#xf…

Spring Cloud 学习笔记(1 / 3)

Spring Cloud 学习笔记&#xff08;2 / 3&#xff09; Spring Cloud 学习笔记&#xff08;3 / 3&#xff09; ---01_前言闲聊和课程说明02_零基础微服务架构理论入门03_第二季Boot和Cloud版本选型04_Cloud组件停更说明05_父工程Project空间新建06_父工程pom文件07_复习Depend…

后缀树/后缀数组

字典树&#xff1a;https://blog.csdn.net/hebtu666/article/details/83141560 后缀树&#xff1a;后缀树&#xff0c;就是把一串字符的所有后缀保存并且压缩的字典树。 相对于字典树来说&#xff0c;后缀树并不是针对大量字符串的&#xff0c;而是针对一个或几个字符串来解决…

kaggle(02)-房价预测案例(基础版)

房价预测案例 Step 1: 检视源数据集 import numpy as np import pandas as pd读入数据 一般来说源数据的index那一栏没什么用&#xff0c;我们可以用来作为我们pandas dataframe的index。这样之后要是检索起来也省事儿。 有人的地方就有鄙视链。跟知乎一样。Kaggle的也是个处…

如何使用github中的pull request功能?

* pull request是社会化编程的象征&#xff0c;通过这个功能&#xff0c;你可以参与到别人开发的项目中&#xff0c;并做出自己的贡献。pull request是自己修改源代码后&#xff0c;请求对方仓库采纳的一种行为*–《github入门与实践》 下面具体说一下github中使用pull reque…

「假装努力」

有多少人在「假装努力」&#xff1f; 又有多少人在「真正成长」&#xff1f; 再努力努力 回想起当年毕业后&#xff0c;在北京和室友合租的日子。 那时&#xff0c;我在工作&#xff0c;室友在培训。 一天&#xff0c;我下班回来&#xff0c;听见他在电话里和家人争吵&…

如何阅读论文?

本文主要讲述了如何才能高效的阅读一篇论文&#xff01;&#xff01;

数据结构课上笔记8

串的概念&#xff1a;串&#xff08;字符串&#xff09;&#xff1a;是由 0 个或多个字符组成的有限序列。 通常记为&#xff1a;s ‘ a1 a2 a3 … ai …an ’ ( n≥0 )。 串的逻辑结构和线性表极为相似。 一些串的类型&#xff1a; 空串&#xff1a;不含任何字符的串&#x…

Numpy 入门

Numpy 入门 Numpy简介 官网链接&#xff1a;http://www.numpy.org/NumPy是Python语言的一个扩充程序库。支持高级大量的维度数组与矩阵运算&#xff0c;此外也针对数组运算提供大量的数学函数库 Numpy的基本功能 快速高效的多维数组对象ndarray用于对数组执行元素级计算以…

数据结构课上笔记10

树 树的定义&#xff1a;树(Tree)是 n(n≥0)个结点的有限集。若 n0&#xff0c;称为空树&#xff1b;若 n > 0&#xff0c;则它满足如下两个条件&#xff1a; (1) 有且仅有一个特定的称为根 (Root) 的结点&#xff1b; (2) 其余结点可分为 m (m≥0) 个互不相交的有限…

pandasStudyNoteBook

pandas 入门培训 pandas简介 - 官网链接&#xff1a;http://pandas.pydata.org/ - pandas pannel data data analysis - Pandas是python的一个数据分析包 , Pandas最初被作为金融数据分析工具而开发出来&#xff0c;因此&#xff0c;pandas为时间序列分析提供了很好的支持 …

二叉树最长路径

分析&#xff1a; 暴力求每一段距离也可。 对于以本节点为根的二叉树&#xff0c;最远距离有三种可能&#xff1a; 1&#xff09;最远路径来自左子树 2 &#xff09;最远路径来自右子树&#xff08;图示与左子树同理&#xff09; 3&#xff09;最远路径为左右子树距离根最远…