汉诺塔(tower of Hanoi)问题的python实现以及理解 您所在的位置:网站首页 python中什么是递归函数 汉诺塔(tower of Hanoi)问题的python实现以及理解

汉诺塔(tower of Hanoi)问题的python实现以及理解

2023-09-10 21:27| 来源: 网络整理| 查看: 265

汉诺塔问题的python实现以及理解

最近在学习MOOC上嵩天老师讲解的Python语言程序设计(本人觉得讲的非常清晰,十分适合初学者学习Python这门语言),在课堂上老师在讲解递归用法的时候提到了汉诺塔问题,由于是算法初学者,参考了一些前人的理解给出了自己的一些理解与看法。

首先什么是汉诺塔问题,

给出三根柱子,一根柱子自底向上叠着n个圆盘,你需要把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

引用于维基百科

递归函数 话不多说先上代码: #汉诺塔问题 count=0 def move(n,a,b,c): global count if n==1: print ("{}-->{}".format(a,c)) count+=1 else: move(n-1,a,c,b) move(1,a,b,c) move(n-1,b,a,c) move(3,"a","b","c") print(count)

这个问题需要用到递归的特性,用递归编写代码不仅十分简洁而且可以任意指定n的大小。说道python中的递归函数,需要明确基例和链条,然后采用函数+分支语句的写法来完成代码编写。 —基例就是递归的起始点,相当于函数中就是给出的初始值的概念 —链条就是n与n-1的关系。

问题分析 这个问题一开始在老师给出的代码中我看的十分疑惑,然后逐渐慢慢理解,现在我给出一些解决问题的关键:

— 我们需要移动很多圆盘但是我们可以抽象理解为只关心n与n-1个圆盘之间的关系,这也是递归的分析的原则,所以我们可以将n个圆盘划分为n-1个和1个。 问题可以简化为此时我们只需要首先将n-1个圆盘从A柱移动到B上,然后再把最下面的1个大圆盘移动到C,最后把B柱子中的n-1个圆盘移动到C上。 —如果我们需要对移动次数进行计数的话可以设置一个变量count,但是这个变量是随着函数的运行需要累积的,所以我们要将它设置为全局变量(global保留字实现)。 —对于递归问题我们都可以写为函数+if else语句的形式

好了开始分析每一段代码

count=0 def move(n,a,b,c): global count

这里设置一个计数变量count,同时这个变量需要设置为全局变量。并同时设置一个move函数,变量是圆盘数量n,柱子的序号abc。

if n==1: print ("{}-->{}".format(a,c)) count+=1 else: move(n-1,a,c,b) move(1,a,b,c) move(n-1,b,a,c)

这里有一点难理解,我也是理解了很久才明白的。对于n=1的时候,也就是if语句,我们很清楚知道此时只有一个圆盘,所以直接从a柱子移动到c柱子即可。 对于n不等于1的时候,就需要用到中间的过渡柱子,此时我们首先将n-1个柱子从a移到b,然后再把剩下一个柱子从a移动到c,然后再把n-1个柱子从b移动到c。这就是move()三行代码的含义。 一开始我比较困惑的点在于为什么这个函数改变自变量就可以实现递归移动的功能。后来我明白了因为是递归函数的算法原理就是需要反向计算,当你输入一个值比如(3,a,b,c)的时候,由于n不等于1,执行else语句,此时计算机不知道move(2,a,b,c)的值或者功能,此时计算机需要腾出一块内存计算move(2,a,b,c)这个函数,此时新计算n=2的值我们在执行else语句时由于需要n-1,此时就可以知道move(1,a,b,c)这个函数的功能是输出a–>c。这样根据在一开始else语句输入的move(n-1,a,c,b),move(n-1,b,a,c)不同的变量,根据不同变量打印出不同的函数值。

move(3,"a","b","c") print(count)

最后由于定义函数并不运行,我们需要单独写出来这个函数然后赋值变量,就可以打印出相应的变化过程。最后再打印出变化的次数count.

示例:当n=4时候的结果 在这里插入图片描述 写于2020.9.22 ,2:11 a.m.


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有