• 有趣的汉诺塔


    1、汉诺塔的介绍

    从左到右 A  B  C 柱 大盘子在下, 小盘子在上, 借助B柱将所有盘子从A柱移动到C柱, 期间只有一个原则: 大盘子只能在小盘子的下面.

    如果有3个盘子, 大中小号, 越小的越在上面, 从上面给盘子按顺序编号 1(小),2(中),3(大), 后面的原理解析引用这里的编号.

    2、解决方法

           递归简单来说就是方法内部自己调用自己, 同时也一定有一个结束点. 如果对方法调用栈了解的话,其实是很容易理解方法的调用过程的, 就是从主线程开始调用方法进行不停的压栈和出栈操作. 方法的调入就是将方法压入栈中, 方法的结束就是方法出栈的过程, 这样保证了方法调用的顺序流. 如果跟踪递归的调用情况会发现也是如此, 到最后一定是这个方法最后从栈中弹出回到主线程, 并且结束.

    栈的特点:先进后出。 比如一个方法 A 自己调用自己, 我用编号区分一下进栈过程:

    A -> A(1) -> A(2) -> A(3)

    在A(3)时满足某种条件得以退出, 回到 A(2), A(2)结束回到A(1), 再回到A, 出栈过程:

    A(3) -> A(2) -> A(1) -> A

    对于递归,还有一个形象的认识,就是我小时候家里有一个柜子, 柜子两端都是玻璃, 头伸进柜子看一面镜子,会看到镜子里还有镜子, 然后镜子里还有镜子, 但和递归的特点不同的是这镜子的反射是没有尽头的, 只要眼睛一直能看到底的话.

    了解完递归后, 再回头来看如何用递归的方式解决汉诺塔的问题.

    三、问题解决

    (1) 代码实现

    ''' 编程环境:python3.7  win7x64 '''
    from turtle import *
    class Stack:
        def __init__(self):
            self.items = []
        def isEmpty(self):
            return len(self.items) == 0
        def push(self, item):
            self.items.append(item)
        def pop(self):
            return self.items.pop()
        def peek(self):
            if not self.isEmpty():
                return self.items[len(self.items) - 1]
        def size(self):
            return len(self.items)
    
    def drawpole_1(k):#画汉诺塔的底座
        up()
        pensize(10)
        speed(100)
        goto(400*(k-1), 100)
        down()
        goto(400*(k-1), -100)
        goto(400*(k-1)-20, -100)
        goto(400*(k-1)+20, -100)
    
    def drawpole_3():#画出汉诺塔的三个底座
        hideturtle()#隐藏
        drawpole_1(0)#画出汉诺塔的底座左
        drawpole_1(1)#画出汉诺塔的底座中
        drawpole_1(2)#画出汉诺塔的底座右
    
    def creat_plates(n):#制造n个盘子
        plates=[Turtle() for i in range(n)]
        for i in range(n):
            plates[i].up()
            plates[i].hideturtle()
            plates[i].shape("square")
            plates[i].shapesize(1,8-i)
            plates[i].goto(-400,-90+20*i)
            plates[i].showturtle()
        return plates
    
    def pole_stack():#制造底座的栈
        poles=[Stack() for i in range(3)]
        return poles
    
    def moveDisk(plates,poles,fp,tp):#把poles[fp]顶端的盘子plates[mov]从poles[fp]移到poles[tp]
        mov=poles[fp].peek()
        plates[mov].goto((fp-1)*400,150)
        plates[mov].goto((tp-1)*400,150)
        l=poles[tp].size()#确定移动到底部的高度(恰好放在原来最上面的盘子上面)
        plates[mov].goto((tp-1)*400,-90+20*l)
    
    def moveTower(plates,poles,height,fromPole, toPole, withPole):#递归放盘子
        if height >= 1:
            moveTower(plates,poles,height-1,fromPole,withPole,toPole)
            moveDisk(plates,poles,fromPole,toPole)
            poles[toPole].push(poles[fromPole].pop())
            moveTower(plates,poles,height-1,withPole,toPole,fromPole)
    
    myscreen=Screen()
    setup(1200,500) #设置窗口大小
    drawpole_3()    #画汉诺塔的底座
    n=int(input("请输入汉诺塔的层数并回车:"))#输入汉诺塔的盘子数
    plates=creat_plates(n)#制造n个盘子
    poles=pole_stack()
    for i in range(n):
        poles[0].push(i)
    moveTower(plates,poles,n,0,2,1)
    myscreen.exitonclick()

      (2) 汉诺塔图



  • 相关阅读:
    servletContext
    解决Response输出时乱码
    servletConfig
    服务器和浏览器交互过程
    myeclipse配置
    servlet
    http协议
    配置虚拟主机
    配置主页
    开网站步骤
  • 原文地址:https://www.cnblogs.com/lzxbs/p/10612438.html
Copyright © 2020-2023  润新知