zoukankan      html  css  js  c++  java
  • 汉诺塔递归算法拙见

    逛C++吧的时候看到一个人说看不懂汉诺塔递归算法,我去玩了下发现就是小时候学习机上的一个游戏啊,那时候认为相当有难度,4个就弄不出来了尴尬

    之后细致分析了一下,发现还挺有意思的。


    先看看大致的步骤:

    1个盘

    1       a       c

    2个盘

    1      a       b

    2       a       c

    1       b       c

    3个盘

    1       a       c

    2       a       b

    1       c       b

    3       a       c

    1       b       a

    2       b       c

    1       a       c

    4个盘

    1       a       b

    2       a       c

    1       b       c

    3       a       b

    1       c       a

    2       c       b

    1       a       b

    4       a       c

    1       b       c

    2       b       a

    1       c       a

    3       b       c

    1       a       b

    2       a       c

    1       b       c

    说明:编号为


    a为左柱子,b为中间柱子。c为右柱子

    目标是把全部盘移动到c位置。详细规则我就不细说了~


    文字难以理解,我就多多上图吧


    分析:

    电脑的计算力和记忆力超群,可是智商低的能够,所以它仅仅能看到事物表面,我们仅仅须要告诉它有两个盘的时候该怎么做


    那么如今有4个盘。我们能够:

    把1-3看成是一个盘,而且记住这个操作,那么如今仅仅有3,4两个盘,电脑就知道该怎么做了:

    可是在进行第一步将3移动到中间柱子的时候,我们还须要进去,就像做梦中梦一样,如今变成了:

    目标变成了将3之上的全部盘移动到中间柱子,当然,在把2移动到借用位置的时候,我们还要进去......

    下面省略XXX字。我们跳到最后一个

    当仅仅有最后一个的时候,我们就直接移动到目标位置咯(注意是目标位置,不是最右的柱子。每一步的目标都会改变,所以我们得依据上一层函数的指示移动),然后跳出

    下面再省略XXX字......


    在经过不断进入和不断出去之后(所以说电脑的记忆力超群)。我们全部的盘就都移动到终于目标了,以下上代码:

    #include <iostream>
    using namespace std;
    
    void move(int num,int loc_now,int loc_next,int loc_aim);
    void move_cout(int num,int loc_now,int loc_next);
    
    #define LOC_A		1	//初始位置
    #define LOC_B		2	//借用位置
    #define LOC_AIM		3	//目标位置
    //每一个位置的详细作用还要看详细情况,或许LOC_B是目标位置。LOC_AIM是借用位置。这是个宏观的作用
    
    int main()
    {
    	int number;
    	cout<<"please input number"<<endl;
    	cin>>number;
    	move(number,LOC_A,LOC_B,LOC_AIM);
    
    	return 0;
    }
    
    /******************************************************
    int num:此盘的编号
    int loc_now:此盘如今所在的位置
    int loc_use:将借用此位置移动到目标位置
    int loc_aim:目标位置
    *******************************************************/
    void move(int num,int loc_now,int loc_use,int loc_aim)
    {
    	if(num==1)//假设仅仅剩最后一个,直接移动到目标位置
    	{
    		move_cout(num,loc_now,loc_aim);
    	}
    	else
    	{
    		move(num-1,loc_now,loc_aim,loc_use);//先把除了最以下那个盘移动到借用位置
    
    		move_cout(num,loc_now,loc_aim);//把最以下的盘移动到目标位置
    
    		move(num-1,loc_use,loc_now,loc_aim);//再把除了最以下那个盘移动到目标位置
    	}
    }
    
    /******************************************************
    int num:此盘的编号
    int loc_now:此盘如今所在的位置
    int loc_next:将要移动到的位置
    *******************************************************/
    void move_cout(int num,int loc_now,int loc_next)
    {
    	cout<<"num-"<<num<<" move from LOC_:"<<loc_now<<" to LOC_:"<<loc_next<<endl;
    }
    



    没想到代码这么短,我们看下执行结果:



    
    		move(num-1,LOC_B,LOC_A,LOC_AIM);
  • 相关阅读:
    费马小定理
    Big Number阶乘位数计算(斯特林公式)
    V
    矩阵快速幂求斐波那契
    奇迹
    缘分
    求导
    拓扑排序
    线段树
    单调栈
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5096880.html
Copyright © 2011-2022 走看看