汉诺塔递归算法拙见

逛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);
时间: 2024-10-11 06:29:50

汉诺塔递归算法拙见的相关文章

C语言之算法初步(汉诺塔--递归算法)

个人觉得汉诺塔这个递归算法比电子老鼠的难了一些,不过一旦理解了也还是可以的,其实网上也有很多代码,可以直接参考.记得大一开始时就做过汉诺塔的习题,但是那时代码写得很长很长,也是不理解递归的结果.现在想起来汉诺塔的算法就3个步骤:第一,把a上的n-1个盘通过c移动到b.第二,把a上的最下面的盘移到c.第三,因为n-1个盘全在b上了,所以把b当做a重复以上步骤就好了.所以算法看起来就简单多了.不过,思考过程还是很痛苦的,难以理解.递归中会保存数据的好处在这里又得到体现,太神奇了. 汉诺塔代码如下:

python的递归算法学习(3):汉诺塔递归算法

汉诺塔问题是递归函数的经典应用,它来自一个古老传说:在世界刚被创建的时候有一座钻石宝塔A,其上有64个金蝶.所有碟子按从大到小的次序从塔底堆放至塔顶.紧挨着这座塔有另外两个钻石宝塔B和C.从世界创始之日起,波罗门的牧师就一直在试图把塔A上的碟子移动到C上去,其间借助于塔B的帮助.每次只能移动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面.当牧师们完成这个任务时,世界末日也就到了. 对于汉诺塔问题的求解,可以通过以下3步实现: (1)将塔A上的n -1个碟子借助C塔先移动到B塔上: (2)

算法学习(4)----汉诺塔递归算法和非递归算法

学习<算法设计与分析基础>,习题2.4 第5题要求为汉诺塔游戏设计一个非递归的算法. 思,不得其解.看书后答案提示: 你如果做不到,也不要沮丧:这个问题的非递归算法虽然不复杂,但却不容易发现.作为一种安慰,可以在因特网上寻找答案. 好吧,话都说得这么直接了,遂百度之,得到一个感觉很好的答案,略做修改,摘录于下: 原文地址:http://blog.sina.com.cn/s/blog_48e3f9cd01000474.html ##################################

汉诺塔递归算法理解及实现

汉诺塔:(Hanoi)是一种玩具,如图![这里写图片描述] (http://img.blog.csdn.net/20150430225337439) 从左到右 A B C 柱 大盘子在下, 小盘子在上, 借助B柱将所有盘子从A柱移动到C柱, 期间只有一个原则: 大盘子只能在小盘子的下面. 问题理解与描述: 1.问题的理解与描述 问题的形式化表示为: 输入:圆盘数n,3根细杆-- 源杆A.过渡杆B和目标杆C. 输出:圆盘从源杆移动到目标杆过程的最少步骤序列. 2.算法的伪代码: HANOI(n,

题目1458:汉诺塔III(不一样的汉诺塔递归算法)

题目链接:http://ac.jobdu.com/problem.php?pid=1458 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: // // 1458 汉诺塔III.cpp // Jobdu // // Created by PengFei_Zheng on 23/04/2017. // Copyright © 2017 PengFei_Zheng. All rights reserved. // #include <std

汉诺塔递归算法

利用递归算法: 第一步:将n-1个盘子移到B 第二步:将第n个盘子移到C 第三步:将n-1个盘子移到C #include<iostream> using namespace std; int count=0; void move(int n,char a,char b) //n表示盘子号a表示盘子的起始位置 b表示盘子到达的位置 { cout<<a<<"->"<<b<<endl; count++; } void towe

递归算法时间复杂度----汉诺塔

问题:汉诺塔递归算法时间复杂度 算法如下: 解释:size表示汉诺塔的规模,startStack表示汉诺塔起始,endStack 表示完成,midStack表示辅助 def Towers(size,startStack,endStack,midStack): if size == 1: print 'Move disk from ', firstStack, 'to ', endStack else: Towers(size-1,firstStack,midStack,endStack) Tow

经典递归小程序--汉诺塔

#include <stdio.h> /* 思路:1.将1到n-1号盘子借助C移到B上 2.将n号盘子移到C上 3.将1到n-1号盘子借助A移到C上 */ //初始化步数 int i = 0; void move(int,char,char); void hannuota(int,char,char,char); void main(void){ int n; printf("请输入汉诺塔盘子的个数:"); scanf("%d",&n); han

汉诺塔的递归算法

汉诺塔是怎样通过递归算法实现的? 这个问题困扰了我一段时间,今天回过头来想想似乎明白了,因此在这里记录下自己想法. 首先贴上在Python上的代码: 1 # -*- coding: utf-8 -*- 2 3 def move(n,a,b,c): 4 if n == 1: 5 print(a+"-->"+c) 6 if n > 1: 7 move(n-1,a,c,b) 8 print(a+"-->"+c) 9 move(n-1,b,a,c) 10