汉诺塔递归实现C++算法

合集下载

汉诺塔的递归算法

汉诺塔的递归算法

汉诺塔的递归算法1. 汉诺塔问题简介汉诺塔是一种经典的递归问题,常用于理解和展示递归算法的思想。

该问题由法国数学家爱德华·卢卡斯于19世纪初提出,得名于印度传说中一个传说故事。

现代汉诺塔问题由3个塔座和一些盘子组成,目标是将所有盘子从一个塔座上移动到另一个塔座上,遵循以下规则:1.一次只能移动一个盘子;2.大盘子不能放在小盘子上面。

2. 汉诺塔问题的递归解法汉诺塔问题的递归解法是一种简洁、优雅且高效的解决方案。

递归算法是一种将大问题划分为更小子问题的方法,通过递归地解决子问题来解决整个问题。

2.1. 基本思想以三个塔座A、B、C为例,假设有n个盘子需要从A移动到C。

递归算法的基本思想如下:1.将n个盘子分成两部分:最底下的一个盘子和上面的n-1个盘子;2.将上面的n-1个盘子从塔座A移动到塔座B,目标塔座为C;3.将最底下的一个盘子从塔座A移动到塔座C;4.将塔座B上的n-1个盘子移动到塔座C,目标塔座为A。

2.2. 递归实现递归解决汉诺塔问题的关键在于理解递归的调用和返回过程。

具体的递归实现如下:def hanoi(n, a, b, c):# n表示盘子的数量,a、b、c表示3个塔座if n == 1:print("Move disk from", a, "to", c)else:hanoi(n-1, a, c, b)print("Move disk from", a, "to", c)hanoi(n-1, b, a, c)# 调用递归函数hanoi(3, 'A', 'B', 'C')上述代码中,当n等于1时,直接将盘子从塔座A移动到塔座C。

否则,递归地将上面的n-1个盘子从塔座A移动到塔座B,然后将最底下的一个盘子从A移动到C,最后再将塔座B上的n-1个盘子移动到塔座C。

汉诺塔游戏-----用C++编的

汉诺塔游戏-----用C++编的

#ifndef HANIO_H_#define HANIO_Hclass Stack{private:enum{ MAX=50 };int m_node[MAX];int m_top;int m_size;int m_index;public:Stack();~Stack() { };bool Isfull() { return m_top==MAX-1 ;}; //堆栈满则返回TRUE bool Isempty() { return m_top==-1;}; //堆栈空则返回TRUE int Top() { return m_top; };int TopValue() { return m_node[m_top];};int GetDataFromIndex(int i) { return m_node[i]; };int GetIndex() { return m_index; } ;void SetIndex(int index) { m_index = index; };int Size() { return m_top+1; };bool Push(int data);bool Pop(int * pData);int MoveToNext();void OutPrint();};class Hanio{Stack m_stack[3];int m_num; //盘数int m_steps; //移动次数int m_times; //完成所用时间void print(char ch,int n);public:Hanio(int num=3);~Hanio() {};void GameStart();bool MoveFromTo(int x,int y); //从x号盘移动到y号盘void DrawPaletes(char ch='*'); //打印3个堆的盘子bool IsFinished() ; //结束返回TURE;int Solve(char from,char to,char auxiliary,int n); //求解其解法路径};#endif//hanio.cpp#include "hanio.h"#include <iostream>#include<cstdlib>#include<cstring>#include<cctype>#include<windows.h>Stack::Stack(){m_top=-1;m_index=m_top;for(int i=0;i<MAX;i++)m_node[i]=0;}bool Stack::Push(int data){if(Isfull())return false;m_top++;m_node[m_top]=data;m_index=m_top;return true;}bool Stack::Pop(int *pData){if(Isempty())return false;*pData=m_node[m_top];m_node[m_top]=0;m_top--;m_index=m_top;return true;}int Stack::MoveToNext(){int temp=m_index;m_index--;return m_node[temp];}void Stack::OutPrint(){if(m_top!=-1){for(int i=0;i<=m_top;i++)std::cout<<"["<<m_node[i]<<"]";}}///////////////////////////////////////Hanio::Hanio(int num){m_num=num;m_steps=0;m_times=0;for(int i=num;i>=1;i--)m_stack[0].Push(i);//m_stack[0].OutPrint();}void Hanio::print(char ch,int n){for(int i=1;i<=n;i++)std::cout<<ch;}void Hanio::DrawPaletes(char ch){int max;max=m_stack[0].Size()>m_stack[1].Size() ? m_stack[0].Size() : m_stack[1].Size();max=m_stack[2].Size()>max ? m_stack[2].Size() : max;//std::cout<<"Max:"<<max<<std::endl;m_stack[0].SetIndex(max-1);m_stack[1].SetIndex(max-1);m_stack[2].SetIndex(max-1);for(int i=1;i<=max;i++){int data1=m_stack[0].MoveToNext();int data2=m_stack[1].MoveToNext();int data3=m_stack[2].MoveToNext();if(data1==0)print(' ',20);else{print(' ',10-data1);print(ch,2*data1);print(' ',10-data1);}if(data2==0)print(' ',20);else{print(' ',10-data2);print(ch,2*data2);print(' ',10-data2);}if(data3==0)print(' ',20);else{print(' ',10-data3);print(ch,2*data3);print(' ',10-data1);}std::cout<<std::endl;}}bool Hanio::MoveFromTo(int x,int y){m_steps++; //计算所走的步数if(m_stack[x].Isempty()){std::cout<<x<<" pallete is empty ! continue !"<<std::endl; std::cin.get();return false;}if(m_stack[y].Isempty()){int data;m_stack[x].Pop(&data);m_stack[y].Push(data);return true;}else{if(m_stack[x].TopValue()>m_stack[y].TopValue()){std::cout<<"The board can't move from "<<x<<" plate to " <<y<<" plate!"<<std::endl;std::cin.get();return false;}else{int data;m_stack[x].Pop(&data);m_stack[y].Push(data);return true;}}}bool Hanio::IsFinished(){return m_stack[2].Top()==m_num-1;}void Hanio::GameStart(){using namespace std;UINT StartTime=::GetTickCount();UINT EndTime;while(1){system("cls");print('-',80);cout<<"steps: "<<m_steps; print(' ',20);cout<<"Used time: "<<m_times<<endl;print('-',80);cout<<endl; cout<<endl; print(' ',10); cout<<"A";print(' ',19); cout<<"B"; print(' ',19);cout<<"C"<<endl<<endl;Hanio::DrawPaletes();cout<<endl; cout<<endl;print('-',80);//测试游戏是否结束if(Hanio::IsFinished()){cout<<"你好强呀!从今天开始,维护世界和平的任务就交给你那!"<<endl;cin.get();break;}//输入命令并左相应的处理char szCommand[50];cout<<">>";cin.getline(szCommand,50);if(stricmp(szCommand,"QUIT")==0 || stricmp(szCommand,"Q")==0)break;if(stricmp(szCommand,"HELP")==0 || stricmp(szCommand,"H")==0){cout<<" 本游戏说明:"<<endl;cout<<" 该游戏由DAVID用C++编程,花费了一个多下午的时间呢!!!,由命令行来控制铁饼的移动:"<<endl;cout<<" QUIT / Q : 退出程序"<<endl;cout<<" HELP / H : 查看该说明"<<endl;cout<<" XY : X,Y的取值为A,B,C,意思时把X木桩最上面的铁饼移到Y 木桩"<<endl;cout<<" SOLVE / S : 显示求解该问题(移动铁饼)的最优路径..."<<endl; cin.get();}char ch1=toupper(szCommand[0]);char ch2=toupper(szCommand[1]);if( ch1=='A' && ch2=='B')Hanio::MoveFromTo(0,1);else if ( ch1=='A' && ch2=='C')MoveFromTo(0,2);else if ( ch1=='B' && ch2=='A')MoveFromTo(1,0);else if ( ch1=='B' && ch2=='C')MoveFromTo(1,2);else if ( ch1=='C' && ch2=='A')MoveFromTo(2,0);else if ( ch1=='C' && ch2=='B')MoveFromTo(2,1);else{cout<<"Bad command !"<<endl;cin.get();}//统计游戏所用时间EndTime=GetTickCount();m_times=(EndTime-StartTime)/1000;}}int Hanio::Solve(char from,char to,char auxiliary,int n) {if(n==1)return 0;}//main.cpp#include<iostream>#include"hanio.h"#include<cstdlib>using namespace std;int StartPicture();//返回选择的盘数int main(){int number;number=StartPicture();Hanio hanio(number);hanio.GameStart();return 0;}void print(char ch,int n){for(int i=1;i<=n;i++)std::cout<<ch;}int StartPicture(){using namespace std;int number;system("cls");system("color fc");print(' ',20);print('-',25);cout<<endl;print(' ',20);cout<<" Hanio(汉诺塔)"<<endl;print(' ',20);print('-',25);cout<<endl;print(' ',40);print('-',5);cout<<"By David"<<endl;print('=',80);cout<<" 相传在某一座古庙中有3根木桩,有24个铁盘由小到大放置在一根木柱上,庙中流传者一个传说:\"如果能把24个铁盘, 从一根木桩移动到另一个木桩,且必须遵守如下规则:"<<endl;cout<<endl;print(' ',5);cout<<"1. 每天只能动一个盘,而且只能从最上面的铁盘开始搬动."<<endl; print(' ',5);cout<<"2. 必须维持较小的铁盘在上方的原则"<<endl;cout<<endl;cout<<"这两个原则,则当24个铁盘完全般到另一个木桩时,世界就回永久和平!!"<<endl;cout<<"游戏的玩法可以在命令行中输入HELP查看"<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<"再此输入你要搬的铁盘数(建议在1--10值间,太多回花费很长时间的)"<<endl;print('=',80);cout<<">>";cin>>number;cin.get();system("cls");return number;}。

汉诺塔函数

汉诺塔函数

汉诺塔函数
汉诺塔函数,又称为河内塔函数,是一种经典的递归算法。

该算法的目的是将一堆盘子从一个柱子移动到另一个柱子,同时遵循以下规则:
1. 每次只能移动一个盘子;
2. 每次移动必须将盘子从较小的柱子移动到较大的柱子上;
3. 每个盘子只能放在比它大的盘子上面。

汉诺塔函数的实现过程是将问题分解成更小的问题,通过递归的方式解决。

具体实现方法如下:
1. 如果只有一个盘子,直接将它移动到目标柱子上;
2. 如果有多个盘子,将它们看作两部分:最底下的一个盘子和上面的所有盘子。

先将上面的所有盘子移动到辅助柱子上,再将最底下的盘子移动到目标柱子上,最后将辅助柱子上的盘子移动到目标柱子上。

通过反复执行上述操作,即可将所有盘子从起始柱子移动到目标柱子上。

汉诺塔函数是一种经典的递归算法,具有较高的实用价值。

在程序设计中,我们可以通过该函数解决一些具有相似结构的问题,如排序、搜索等。

- 1 -。

数据结构汉诺塔递归算法

数据结构汉诺塔递归算法

数据结构汉诺塔递归算法1. 什么是汉诺塔问题汉诺塔(Hanoi)是由法国数学家爱德华·卢卡斯(Édouard Lucas)在19世纪初提出的一个经典数学问题。

问题的描述如下:假设有3个柱子(标记为A、B、C),其中柱子A上有n个不同大小的圆盘,按照从上到下的顺序由小到大放置。

现在要将这n个圆盘按照相同的顺序移动到柱子C 上,期间可以借助柱子B。

在移动时,要遵循以下规则:1.每次只能移动一个圆盘;2.每个圆盘只能放置在比它大的圆盘上面;3.只能借助柱子B进行中转。

汉诺塔问题的目标是找到一种最优策略,使得完成移动所需的步骤最少。

2. 汉诺塔问题的递归解法汉诺塔问题的递归解法非常简洁和优雅。

下面就来详细介绍递归解法的思路和步骤。

2.1. 基本思路我们先来思考一个简化版的问题:将柱子A上的n个圆盘移动到柱子B上。

为了实现这个目标,可以进行如下步骤:1.将A柱上的n-1个圆盘通过借助柱子B移动到柱子C上;2.将A柱上的第n个圆盘直接移动到柱子B上;3.将柱子C上的n-1个圆盘通过借助柱子A移动到柱子B上。

根据上述思路,我们可以发现一个递归的规律:将n个圆盘从A柱移动到B柱,可以分解为两个子问题,即将n-1个圆盘从A柱移动到C柱,和将n-1个圆盘从C柱移动到B柱。

2.2. 递归实现根据以上思路,我们可以编写一个递归函数来实现汉诺塔问题的解决。

def hanoi(n, A, B, C):if n == 1:print(f"Move disk {n} from {A} to {B}")else:hanoi(n-1, A, C, B)print(f"Move disk {n} from {A} to {B}")hanoi(n-1, C, B, A)这个递归函数接受4个参数:n 表示圆盘的数量,A、B、C 表示3根柱子的名称。

当 n 为 1 时,直接将圆盘从 A 移动到 B。

python汉诺塔递归详解

python汉诺塔递归详解

python汉诺塔递归详解汉诺塔是一种经典的数学谜题,它可以通过递归算法解决。

汉诺塔问题的目标是将一个由圆盘组成的塔从一根柱子上移动到另一根柱子上,每次只能移动一个圆盘,并且不能将较大的圆盘放在较小的圆盘上面。

以下是一个用Python编写的汉诺塔递归解法的详细步骤:步骤1:定义汉诺塔函数,接收三个参数:圆盘数量n,起始柱子A,目标柱子C。

辅助柱子B可以通过 A、B、C 三个柱子中剩余的柱子确定。

步骤2:递归结束条件是只剩下一个圆盘,此时直接将它从起始柱子移动到目标柱子。

步骤3:递归调用。

将除了最大的圆盘外的所有圆盘从起始柱子移动到辅助柱子(利用递归调用),然后将最大的圆盘从起始柱子移动到目标柱子,最后再将所有圆盘从辅助柱子移动到目标柱子(利用递归调用)。

以下是用Python代码实现的汉诺塔递归解法:```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)n = int(input("请输入圆盘数量:"))hanoi(n, 'A', 'B', 'C')```这段代码首先定义了一个名为`hanoi`的函数,接收四个参数:圆盘数量`n`、起始柱子`A`、辅助柱子`B`、目标柱子`C`。

如果圆盘数量`n`等于1,那么就直接将圆盘从起始柱子`A`移动到目标柱子`C`;否则,先将`n-1`个圆盘从起始柱子`A`通过辅助柱子`B`移动到目标柱子`C`,然后将最大的圆盘从起始柱子`A`移动到目标柱子`C`,最后再将剩余的`n-1`个圆盘从辅助柱子`B`通过起始柱子`A`移动到目标柱子`C`。

汉诺塔问题数学解法

汉诺塔问题数学解法

汉诺塔问题数学解法汉诺塔问题是一个经典的数学难题,也是计算机科学中的常见算法题目。

在这个问题中,我们需要将三个塔座上的圆盘按照一定规则从一座塔移动到另一座塔,只能每次移动一个圆盘,并且在移动过程中始终保持大圆盘在小圆盘下面。

为了解决汉诺塔问题,我们首先需要了解递归的概念。

递归是一种问题解决方法,其中问题被分解为更小的子问题,直到最小的问题可以直接解决。

在汉诺塔问题中,我们可以使用递归来实现移动圆盘的步骤。

设有三个塔座,分别为A、B、C,并且初始时所有的圆盘都在A 塔上,我们的目标是将所有的圆盘移动到C塔上。

为了方便讨论,我们将最小的圆盘称为第1号圆盘,次小的圆盘称为第2号圆盘,以此类推,最大的圆盘称为第n号圆盘。

解决汉诺塔问题的数学解法如下:1. 当只有一个圆盘时,直接将它从A塔移动到C塔,移动结束。

2. 当有两个或以上的圆盘时,可以按照以下步骤进行移动:(1) 先将上面n-1个圆盘从A塔移动到B塔(借助C塔)。

(2) 将第n号圆盘从A塔移动到C塔。

(3) 最后将n-1个圆盘从B塔移动到C塔(借助A塔)。

通过以上步骤,我们可以将n个圆盘从A塔移动到C塔,完成整个汉诺塔问题的解。

这个数学解法的正确性可以通过递归的思想来解释。

当有n个圆盘时,我们需要借助第三个塔座将前n-1个圆盘移动到B塔上,然后将第n号圆盘移动到C塔上,最后再将n-1个圆盘从B塔移动到C塔上。

这个过程可以看作是一个递归过程,我们首先需要将前n-1个圆盘从A 塔移动到B塔上,然后再将第n号圆盘从A塔移动到C塔上,最后再将n-1个圆盘从B塔移动到C塔上。

通过不断缩小问题规模,我们最终可以将整个汉诺塔问题解决。

总结起来,汉诺塔问题是一个经典的数学难题,解决这个问题可以使用递归的数学解法。

通过将问题分解为更小的子问题,我们可以将n 个圆盘从一座塔移动到另一座塔上。

这个数学解法的正确性可以通过递归的思想来解释。

希望通过以上的介绍,您对汉诺塔问题的数学解法有了更深入的理解。

python汉诺塔递归详解(一)

python汉诺塔递归详解(一)

python汉诺塔递归详解(一)Python汉诺塔递归解法引言汉诺塔(Hanoi Tower)是一种数学问题和益智游戏,由法国数学家爱德华·卢卡教授在19世纪初提出。

通过计算机编程解决汉诺塔问题,可以帮助我们更好地理解递归算法在编程中的应用。

问题描述在汉诺塔问题中,有三个柱子和一些圆盘,每个柱子上的圆盘按照从小到大的顺序叠放。

问题的目标是将所有圆盘从一根柱子移动到另一根柱子上,每次只能移动一个圆盘,并且在移动过程中不允许大圆盘放在小圆盘上面。

解法思路我们可以使用递归的方法解决汉诺塔问题。

下面是解决汉诺塔问题的基本步骤:1.将上面n-1个圆盘从A柱移动到B柱。

2.将最大的圆盘从A柱移动到C柱。

3.将B柱上的n-1个圆盘移动到C柱。

通过递归调用这三个步骤,可以将所有的圆盘从A柱移动到C柱。

代码实现以下是使用Python语言实现汉诺塔递归的代码:def hanoi(n, A, B, C):if n == 1:print("Move disk 1 from", A, "to", C) returnhanoi(n-1, A, C, B)print("Move disk", n, "from", A, "to", C) hanoi(n-1, B, A, C)# 测试代码hanoi(3, "A", "B", "C")运行结果运行上述代码,我们可以得到以下输出结果:Move disk 1 from A to CMove disk 2 from A to BMove disk 1 from C to BMove disk 3 from A to CMove disk 1 from B to AMove disk 2 from B to CMove disk 1 from A to C总结通过递归算法,我们可以轻松解决汉诺塔问题。

c语言汉诺塔问题递归算法

c语言汉诺塔问题递归算法

c语言汉诺塔问题递归算法汉诺塔问题是经典的递归问题,要求将n个大小不同的盘子从起始柱移动到目标柱,并遵循以下规则:1.大盘子不能在小盘子上方移动。

2.每次只能移动一个盘子。

在C语言中,我们可以使用递归算法来解决汉诺塔问题。

以下是一个简单的示例代码:```c#include<stdio.h>voidhanoi(intn,charfrom,charto,charaux){if(n==1){//只有一个盘子时,直接移动到目标柱printf("Movedisk1from%cto%c\n",from,to);}else{//递归地将n-1个盘子从起始柱移动到辅助柱,再将最后一个盘子从起始柱移动到目标柱hanoi(n-1,from,aux,to);printf("Movedisk%dfrom%cto%c\n",n,from,to);hanoi(n-1,aux,to,from);}}intmain(){intn;printf("Enterthenumberofdisks:");scanf("%d",&n);hanoi(n,'A','C','B');//从起始柱A开始,目标柱C,辅助柱Breturn0;}```在上述代码中,我们定义了一个名为hanoi的函数,用于实现汉诺塔问题的递归解法。

该函数接受四个参数:n表示盘子的数量,from表示起始柱,to表示目标柱,aux表示辅助柱。

当只有一个盘子时,直接移动到目标柱;否则,我们通过递归调用将n-1个盘子从起始柱移动到辅助柱,再将最后一个盘子从起始柱移动到目标柱。

在主函数中,我们从用户输入获取盘子的数量,并调用hanoi函数开始解决问题。

通过使用递归算法,我们可以将复杂的问题分解为更小的子问题,从而方便地解决问题。

在汉诺塔问题中,我们将n个盘子从起始柱移动到目标柱的问题分解为将n-1个盘子从起始柱移动到辅助柱和将最后一个盘子从起始柱移动到目标柱两个子问题。

汉诺塔实验报告

汉诺塔实验报告

汉诺塔实验报告概述汉诺塔问题是一道经典的递归问题,它可以帮助我们理解递归算法的原理和应用。

本实验旨在通过构建汉诺塔模型,观察和分析不同圆盘数量下移动次数的变化规律,验证汉诺塔问题的递归算法。

实验方法1. 准备工作- 需要一套汉诺塔游戏模型,包括3个底座和若干个不同大小的圆盘。

- 建立记录移动次数的计数器。

2. 实验步骤- 将所有圆盘从初始底座A移至目标底座C,中间底座为B。

- 初始时,所有圆盘按照从小到大的顺序堆叠在底座A上。

- 按照汉诺塔问题的规则,每次只能移动一个圆盘,并且大圆盘不能叠在小圆盘上。

- 记录每次移动的步数,直到所有圆盘都移动到目标底座C上。

3. 实验参数- 按照实验要求,分别记录3个圆盘、4个圆盘、5个圆盘时的移动次数。

- 实验过程中,需要注意每次移动的顺序和底座。

实验结果与分析根据上述实验方法,进行了汉诺塔问题的实验,并记录了移动次数。

实验数据如下:圆盘数量移动次数3 74 155 31通过观察实验数据,我们可以发现汉诺塔问题的移动次数与圆盘数量之间存在以下关系:移动次数 = 2^n - 1,其中n为圆盘数量。

推导过程如下:- 当圆盘数量为3时,移动次数 = 2^3 - 1 = 8 - 1 = 7,与实验数据一致。

- 当圆盘数量为4时,移动次数 = 2^4 - 1 = 16 - 1 = 15,与实验数据一致。

- 当圆盘数量为5时,移动次数 = 2^5 - 1 = 32 - 1 = 31,与实验数据一致。

结论通过本次实验,我们验证了汉诺塔问题的递归算法。

实验结果表明,汉诺塔问题的移动次数与圆盘数量之间存在2^n - 1的关系。

这个规律可以用数学归纳法进行证明,也可以通过递归算法的实现得到。

递归算法的核心思想是将大问题划分为更小的子问题,并通过递归地解决子问题来解决整个问题。

在汉诺塔问题中,每次移动需要借助一个中间底座,将n-1个圆盘从初始底座移至中间底座,然后将最大的圆盘从初始底座移至目标底座,最后将n-1个圆盘从中间底座移至目标底座。

汉诺塔递归算法详细解析(C语言版)

汉诺塔递归算法详细解析(C语言版)

汉诺塔递归算法详细解析(C语⾔版)汉诺塔代码:1// 汉诺塔2 # include <stdio.h>3void hanoi ( int n, char a, char b, char c ) //这⾥代表将a柱⼦上的盘⼦借助b柱⼦移动到c柱⼦4 { if (1 == n) //如果是⼀个盘⼦直接将a柱⼦上的盘⼦移动到c5 {6 printf("%c-->%c\n",a,c);7 }8else9 {10 hanoi ( n-1, a, c, b ) ; //将a柱⼦上n-1个盘⼦借助c柱⼦,移动到b柱⼦11 printf("%c-->%c\n",a , c) ; //再直接将a柱⼦上的最后⼀个盘⼦移动到c12 hanoi ( n-1, b, a, c ) ; //然后将b柱⼦上的n-1个盘⼦借助a移动到c13 }14 }15int main ()16 { int n ;17 printf( "Input the number of diskes:") ;18 scanf("%d",&n) ;19 hanoi ( n, 'A' , 'B' , 'C' ) ;20return0;21 }算法分析:(步骤1) 如果是⼀个盘⼦ 直接将a柱⼦上的盘⼦从a移动到c 否则(步骤2) 先将a柱⼦上的n-1个盘⼦借助c移动到b(图1), 肯定没有c柱⼦是不能移动的,已知函数形参是hanoi(int n,char a,char b,char c)。

代表将a柱⼦上的盘⼦借助c柱⼦移动到b柱⼦,这⾥调⽤函数的时候是将a柱⼦上的n-1个 盘⼦借助c柱⼦,移动到b柱⼦。

所以这⾥需要将位置调换⼀下hanoi(n-1,a,c,b)。

(步骤3) 此时移动完如图1,但是还没有移动结束,⾸先要将a柱⼦上的最后⼀个盘⼦(第n个)盘⼦直接移动到c(图2)(步骤4) 最后将b柱⼦上的n-1个盘⼦借助a移动到c(图3)这样递归算法就完成了。

C语言递归调用实例——汉诺塔问题动画实现(附完整代码)

C语言递归调用实例——汉诺塔问题动画实现(附完整代码)
6
二、程序框架
古人云,不谋全局者,不足谋一域。同样,在编写代码之前,我们必 须得有个大体的思路和整体上的把握。不能一上来就稀里糊涂地乱敲一通。 当然,这里我也只能仅仅谈自己的个人想法,不一定就是最优的解决方案, 还希望能和大家一起相互交流,共同进步。整个程序的框架,我把它分为 动画效果和核心算法两大部分。我首先实现的是动画效果部分,等能够实 现盘子的随意移动后,我才开始研究核心算法的实现。这样一来,在核心 算法部分,我们正好可以利用前面的动画效果来直观地反映出我们的思路, 有助于代码的调试和缩短程序的开发周期。为了尽量减少废话,我们可以 用一张图来进行表示:
图 1-1 移动第一个圆盘..................................................................................................................... 4 图 1-2 移动第二个圆盘...................................................................................................................... 5 图 1-3 移动最后一个圆盘................................................................................................................. 6
能移动一个圆盘,且圆盘在放到棒上时,大的不能放在小的上面。中间的一根
棒作为辅助移动用。” 事实上,对此曾经有人作过分析,按这个规则,众僧耗尽毕生精力也
不可能完成圆盘的移动,因为需要移动圆盘的次数是一个天文数字 18446744073709551615(64 个圆盘需要移动的次数为 2 的 64 次方)。假设 1us 进行一次移动,也需要约一百万年的时间,使用计算机也很难解决 64

汉诺(Hanoi)塔问题(C#版)

汉诺(Hanoi)塔问题(C#版)

汉诺(Hanoi)塔问题(C#版)
⼀个只能⽤递归解决的数学问题;问题描述:古代有⼀个梵塔,塔内有3个座,A、B、C,开始时A座有64个盘,盘⼦⼤⼩不等,⼤的在上,⼩的在下。

有⼀个⽼和尚想把这64个盘⼦从A座移到C座(如图所⽰),但每次只允许移动⼀个盘,且在移动过程中在3个座上始终保持⼤盘在下,⼩盘在上。

在移动地程中可以⾏⽤B座,要求编程序打印出移动的步骤。

逆向推理:1.假如⼀个和尚能把上⾯63个盘⼦先搬到B座,第⼆个和尚再把最⼤的那个移到C,第三个和尚再把63个盘⼦移到C座;⾄此整个⼯作就完成的。

2.问题是怎么才能把63个盘⼦移到B座,按照同样的⽅法,先把62个盘⼦选移到C座
,再把第63个盘⼦移到B座,最后再将62个盘⼦移到B座。

3……如此类推;
4.从上⾯分析可以看出:只有等后⾯那个和尚搬完盘⼦,前⾯的和尚才能够去完成任。

让我们来栈的数据结构:数据的处理只在⼀端处理,且是先进后出。

所以⽤递归的⽅法去处理是正确的。

(汉诺塔图)
汉诺塔问题解决⽅案
如果你发现有什么错误之处,请指出!谢谢了。

汉诺塔解法原理

汉诺塔解法原理

汉诺塔解法原理汉诺塔是一道经典的递归问题。

要解决汉诺塔问题,我们需要了解一些递归和分治的基本原理。

汉诺塔问题描述汉诺塔问题是指在一根柱子上按大小顺序放置 N 个盘子,大盘子在下面,小盘子在上面。

现在要求将这些盘子全部移到另一个柱子上,可以借助中间的柱子,但是要满足在移动的过程中始终保持大盘子在下、小盘子在上的原则。

汉诺塔解法汉诺塔问题可以用递归算法求解。

具体解法分为三个步骤:1. 将 n-1 个盘子从 A 移动到 B(借助 C)2. 将第 n 个盘子从 A 移动到 C3. 将 n-1 个盘子从 B 移动到 C(借助 A)其中,第 1 步和第 3 步是递归步骤,第 2 步是基础步骤。

在第 1 步和第 3 步中,我们需要先将 n-1 个盘子从 A 移动到 B(或从 B 移动到A),这是通过递归调用将问题规模缩小实现的。

当问题规模足够小时,基础步骤中进行盘子移动的操作就可以解决问题。

递归基本原理递归算法是一种非常高效的算法,可以解决许多问题。

在使用递归算法时,我们需要注意以下几点:1. 递归函数必须有一个基准条件,这个条件用于判断递归何时停止;2. 递归函数必须能够缩小问题规模,这样才能使得递归过程终止;3. 递归函数必须能够不断地将问题分解为同样的形式,这样才能简化递归算法的实现。

1. 分治算法必须要有一个基础步骤,这个步骤可以解决问题的一部分;2. 分治算法必须能够将问题分为若干个子问题,这些子问题与原问题形式相同;3. 子问题必须能够递归地求解。

总结汉诺塔问题是一道经典的递归问题,可以用递归算法求解。

递归算法的基本原理是基准条件、问题规模缩小和问题形式简化。

重点在递归的时候能够将问题不断缩小,同时保证在基础步骤中能够解决问题的一部分。

分治算法与递归类似,也是一种高效的算法。

分治算法的基本原理是基础步骤、问题分解和递归求解。

分治算法能够将问题分解成若干个子问题,这些子问题与原问题形式相同,这样就能够简化算法实现。

汉诺塔的计算原理及应用

汉诺塔的计算原理及应用

汉诺塔的计算原理及应用
汉诺塔问题简介
汉诺塔问题是一个经典的数学问题,它源于印度一个古老的传说。

问题的规则
很简单:给定三个柱子(编号为A、B和C),在柱子A上有一些不同大小的圆盘,按照从上到下逐渐变大的顺序堆叠在柱子上。

目标是将所有的圆盘移动到柱子C
上,移动过程中可以借助柱子B。

汉诺塔问题的计算原理
汉诺塔问题的计算原理可以通过递归实现。

对于N个圆盘的汉诺塔问题,可以将其分解为三个子问题:将N-1个圆盘从柱子A移动到柱子B,将第N个圆盘从
柱子A移动到柱子C,再将N-1个圆盘从柱子B移动到柱子C。

这样就将问题分
解为规模较小的子问题,可以通过递归解决。

下面是汉诺塔问题的计算原理示例代码:
```python def hanoi(n, source, target, auxiliary): if n > 0: # 将 n-1 个圆盘从源柱
子移动到辅助柱子 hanoi(n-1, source, auxiliary, target)
# 将第 n 个圆盘从源柱子移动到目标柱子
print(\。

汉诺塔问题的程序实现(hanoi塔)

汉诺塔问题的程序实现(hanoi塔)

汉诺塔问题的程序实现(hanoi塔)问题重述:有三根柱A、B、C,在柱A上有N块盘⽚,所有盘⽚都是⼤的在下⾯,⼩⽚能放在⼤⽚上⾯。

现要将A上的N块盘⽚移到C柱上,每次只能移动⼀⽚,⽽且在同⼀根柱⼦上必须保持上⾯的盘⽚⽐下⾯的盘⽚⼩,输⼊任意的N,输出移动⽅法。

(注意:这是⼀个古⽼的传说,传说是如果把64个盘⼦由A柱移到了C柱的话,那么世界末⽇就到了,事实上如果要把64个盘⼦从A柱移到C柱的话,即使⽤计算机运算,也要计算数亿年,所以这个预⾔未必不是真实。

)【分析】我们可以这样考虑,当n=1时,我们只要直接将A柱的盘⼦移到C柱,当n>1时,我们可以先把n-1个盘⼦由A柱通过C柱移到B 柱,此时就可以把A柱剩下的最后⼀个盘⼦直接移到C柱,这样接下来只要把n-1个盘⼦通过A柱移到C 柱即可,如果就构成了递归的思路,我们可以定义个移动过程mov(n,a,b,c)表⽰将n个盘⼦从a通过b移到c1.只要求输出搬运的次数#includeusing namespace std;int m=0;void move(){m++;}void I(int n){if(n==1)move();else{I(n-1);move();I(n-1);}}int main(){I(3);cout<cout<<"输出完毕!"<return 0;}更加简单的⽅法!#includeusing namespace std;int fact(int n){if(n==1)return(1);elsereturn((2*fact(n-1)+1));}int main(){cout<}2.不仅要求输出搬运的次数,⽽且要输出每个步骤的详细搬运#includeusing namespace std;int m=0;void Move(int n,char x,char y){cout<<"把"<m++;}void Hannoi(int n,char a,char b,char c){if(n==1)Move(1,a,c);else{Hannoi(n-1,a,c,b);Move(n,a,c);Hannoi(n-1,b,a,c);}}int main(){int i;cout<<"请输⼊圆盘数"<cin>>i;Hannoi(3,'a','b','c');cout<<"总的搬运次数"<cout<<"输出完毕!"<return 0;}}另外⼀种不利⽤递归的解法(很抱歉,我⾃⼰也没调出来,实在太复杂了)#includeusing namespace std;//圆盘的个数最多为64const int MAX = 1;//⽤来表⽰每根柱⼦的信息struct st{int s[MAX]; //柱⼦上的圆盘存储情况int top; //栈顶,⽤来最上⾯的圆盘char name; //柱⼦的名字,可以是A,B,C 中的⼀个int Top()//取栈顶元素{return s[top];}int Pop()//出栈{return s[top--];}void Push(int x)//⼊栈{s[++top] = x;}} ;long Pow(int x, int y); //计算x^yvoid Creat(st ta[], int n); //给结构数组设置初值void Hannuota(st ta[], long max); //移动汉诺塔的主要函数int main(void){int n;cin >> n; //输⼊圆盘的个数st ta[3]; //三根柱⼦的信息⽤结构数组存储Creat(ta, n); //给结构数组设置初值long max = Pow(2, n) - 1;//动的次数应等于2^n - 1 Hannuota(ta, max);//移动汉诺塔的主要函数system("pause");return 0;}void Creat(st ta[], int n){ta[0].name = 'A';ta[0].top = n-1;//把所有的圆盘按从⼤到⼩的顺序放在柱⼦A 上for (int i=0; ita[0].s[i] = n - i;//柱⼦B,C 上开始没有没有圆盘ta[1].top = ta[2].top = 0;for (int j=0; jta[1].s[j] = ta[2].s[j] = 0;//若n 为偶数,按顺时针⽅向依次摆放A B Cif (n%2 == 0){ta[1].name = 'B';ta[2].name = 'C';}else //若n 为奇数,按顺时针⽅向依次摆放A C B {ta[1].name = 'C';ta[2].name = 'B';}}long Pow(int x, int y){long sum = 1;for (int i=0; isum *= x;return sum;}void Hannuota(st ta[], long max){int k = 0; //累计移动的次数int i = 0;int ch;while (k < max){//按顺时针⽅向把圆盘1 从现在的柱⼦移动到下⼀根柱⼦ch = ta[i%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " <<"Move disk " << ch << " from " << ta[i%3].name <<" to " << ta[(i+1)%3].name << endl;i++;//把另外两根柱⼦上可以移动的圆盘移动到新的柱⼦上if (k < max){ //把⾮空柱⼦上的圆盘移动到空柱⼦上,当两根柱⼦都为空时,移动较⼩的圆if (ta[(i+1)%3].Top() == 0 ||ta[(i-1)%3].Top() > 0 &&ta[(i+1)%3].Top() > ta[(i-1)%3].Top()){ch = ta[(i-1)%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i-1)%3].name<< " to " << ta[(i+1)%3].name << endl;}else{ch = ta[(i+1)%3].Pop();ta[(i-1)%3].Push(ch);cout << ++k << ": " << "Move disk " << ch << " from " << ta[(i+1)%3].name << " to " << ta[(i-1)%3].name << endl; }}}}补充知识:【典型例题1】求阶乘n!#includeusing namespace std;int fact(int n){if(n==0)return(1);elsereturn(n*fact(n-1)); }int main(){cout<。

汉诺塔问题的算法描述

汉诺塔问题的算法描述

汉诺塔问题的算法描述
汉诺塔问题是一种经典的数学难题。

它的基本形式是:有三根柱子,在其中一根柱子上从下往上按大小顺序摆放了n个圆盘,现在要将这n个圆盘移动到另一根柱子上,移动时不能将一个较大的圆盘放在较小的圆盘上面。

请描述一种算法来解决汉诺塔问题。

算法描述:
1. 如果n等于1,则将圆盘从柱子A移到柱子C。

2. 否则,将n-1个圆盘从柱子A移到柱子B,然后将剩余的一个圆盘从柱子A移到柱子C。

3. 最后,将n-1个圆盘从柱子B移到柱子C。

以上算法描述的实现方式为递归。

这种算法的时间复杂度为
O(2^n),因为每个圆盘只会被移动一次,而且每次移动都需要进行一系列操作。

因此,当圆盘数量n增加时,算法的执行时间会呈指数增长。

- 1 -。

c#汉诺塔的递归算法与解析

c#汉诺塔的递归算法与解析

c#汉诺塔的递归算法与解析从左到右 A B C 柱⼤盘⼦在下, ⼩盘⼦在上, 借助B柱将所有盘⼦从A柱移动到C柱, 期间只有⼀个原则: ⼤盘⼦只能在⼩盘⼦的下⾯.如果有3个盘⼦, ⼤中⼩号, 越⼩的越在上⾯, 从上⾯给盘⼦按顺序编号 1(⼩),2(中),3(⼤), 后⾯的原理解析引⽤这⾥的编号.⼩时候玩过这个游戏, 基本上玩到第7个,第8个就很没有耐⼼玩了,并且操作的动作都⼏乎相同觉得⽆聊. 后来学习编程, 认识到递归, ⽤递归解决汉诺塔的算法也是我除了简单的排序算法后学习到的第⼀种算法.⾄于递归,简单来说就是⽅法内部⾃⼰调⽤⾃⼰, 同时也⼀定有⼀个结束点. 如果对⽅法调⽤栈了解的话,其实是很容易理解⽅法的调⽤过程的, 就是从主线程开始调⽤⽅法进⾏不停的压栈和出栈操作. ⽅法的调⼊就是将⽅法压⼊栈中, ⽅法的结束就是⽅法出栈的过程, 这样保证了⽅法调⽤的顺序流. 如果跟踪递归的调⽤情况会发现也是如此, 到最后⼀定是这个⽅法最后从栈中弹出回到主线程, 并且结束.栈的特点:先进后出。

⽐如⼀个⽅法 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 - 假设只有⼀个盘⼦的时候, 盘⼦数量 N=1只有⼀个步骤将第1个盘⼦从A移动到C, 为了对⽐⽅便我这样来描述这个步骤:步骤盘⼦编号从柱⼦移动移动到柱⼦1 1 A C案例 2 - 如果有两个盘⼦, 盘⼦数量 N = 2步骤盘⼦编号从柱⼦移动移动到柱⼦1 1 A B2 2 A C3 1 B C案例 3 - 如果有三个盘⼦, 盘⼦数量 N = 3步骤盘⼦编号从柱⼦移动移动到柱⼦1 1 A C2 2 A B3 1 C B4 3 A C5 1 B A6 2 B C7 1 A C如何找出盘⼦移动的规律?我们要做的最重要的⼀件事情就是永远要把最底下的⼀个盘⼦从 A 移动到 C看看上⾯从1个盘⼦的移动到3个盘⼦的移动, 在移动记录中,当盘⼦的编号和盘⼦数量相同的时候他们的步骤都是从A移动到C (看加粗的部分),其它的步骤对等.再观察第3个案例中的第 1-3 步和第 5-7步第 1-3 步⽬的是从 A 移动到 B 如果我们把 B 当作终点, 那么这⾥的第 1-3 步理解起来和第2个案例的三个步骤完全相同, 都是通过⼀个柱⼦来移动,和第2个案例⽐起来在后⾯加括号来表⽰1 1 A C ( A -> B)2 2 A B ( A -> C)3 1 C B ( B -> C)总结:将盘⼦B变成C即可.第 5-7 步⽬的是从 B 移动到 C 如果我们把 C 当作终点, 那么这⾥的 5-7 步理解起来和上⾯也是⼀样的, 和第2个案例的三个步骤也完全相同.和第2个案例⽐起来就是:5 1 B A ( A -> B)6 2 B C ( A- > C)7 1 A C ( B -> C)总结: 将盘⼦B变成A即可根据这个演⽰可以明确⼏点规律:1. 当盘⼦只有⼀个的时候,只有⼀个动作从 A 移动到 C 即结束.2. 当有N个盘⼦的时候, 中间的动作都是从 A 移动到 C, 那么表⽰最下⾯的第N个盘⼦移动完毕3. 中间动作之上都可以认为是: 从 A 移动到 B4. 中间动作之下都可以认为是: 从 B 移动到 C2,3,4 可以表⽰为1 1 A B2 2 A C3 1 B C这种结构⼀直在重复进⾏,C#不太熟悉,试着写写,就有了以下代码:复制代码代码如下:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace DataStructure{class HanoiTower{public void MoveDisk(int DiskQuantity,string PositionA, string PositionB, string PositionC){// If there's only one disk, then end.if (DiskQuantity == 1){Console.WriteLine("Move disk from position {0} to {1}.", PositionA, PositionC);// Must returnreturn;}else{// Step 1 - Change B to C (A --> B)MoveDisk(DiskQuantity - 1, PositionA,PositionC,PositionB);// Step 2 - No changes (A --> C)MoveDisk(1, PositionA, PositionB, PositionC);// Step 3 - Change B to A (A --> C)MoveDisk(DiskQuantity - 1, PositionB, PositionA, PositionC);}}static void Main(string[] args){HanoiTower hanoi = new HanoiTower();Console.WriteLine("Please input Disk Quantity:");int DiskQuantity = Convert.ToInt32(Console.ReadLine());hanoi.MoveDisk(DiskQuantity, "A", "B", "C");Console.ReadKey();}}}结合上⾯的分析,最重要的就是这⾥的3步交换动作, 中间从 A到C的动作是最底层盘⼦的最终操作.// Step 1 - Change B to C (A --> B)MoveDisk(DiskQuantity - 1, PositionA,PositionC,PositionB);// Step 2 - No changes (A --> C)MoveDisk(1, PositionA, PositionB, PositionC);// Step 3 - Change B to A (A --> C)MoveDisk(DiskQuantity - 1, PositionB, PositionA, PositionC);⾄于第1个参数为什么是DiskQuantity - 1,或者1 ⼤家再回到上⾯看看是不是所有的步骤都是.. 1. 1,2,1. 1,2,1,3,1,2,1 这种以盘⼦数对称的结构,⽽它前后都是重复1,2,1 的过程.。

汉诺塔算法

汉诺塔算法

汉诺塔算法汉诺塔算法的递归实现C++源代码#include <fstream>#include <iostream>using namespace std;ofstream fout(“out.txt”);void Move(int n,char x,char y){fout<<“把”<<n<<“号从”<<x<<“挪动到”<<y<<endl;}void Hannoi(int n,char a,char b,char c){if(n==1)Move(1,a,c);else{Hannoi(n-1,a,c,b);Move(n,a,c);Hannoi(n-1,b,a,c);}}int main(){fout<<“以下是7层汉诺塔的解法:”<<endl;Hannoi(7,…a‟,…b‟,…c‟);fout.close();cout<<“输出完毕!”<<endl;return 0;}●汉诺塔算法的递归实现C源代码:#include<stdio.h>void hanoi(int n,char A,char B,char C){if(n==1){printf(“Move disk %d from %c to %c\n”,n,A,C); }else{hanoi(n-1,A,C,B);printf(“Move disk %d from %c to %c\n”,n,A,C); hanoi(n-1,B,A,C);}}main(){int n;printf(“请输入数字n以解决n阶汉诺塔问题:\n”);scanf(“%d”,&n);hanoi(n,…A‟,…B‟,…C‟);}●汉诺塔算法的非递归实现C++源代码#include <iostream>using namespace std;//圆盘的个数最多为64const int MAX = 64;//用来表示每根柱子的信息struct st{int s[MAX]; //柱子上的圆盘存储情况int top; //栈顶,用来最上面的圆盘char name; //柱子的名字,可以是A,B,C中的一个int Top()//取栈顶元素{return s[top];}int Pop()//出栈{return s[top–];}void Push(int x)//入栈{s[++top] = x;}} ;long Pow(int x, int y); //计算x^yvoid Creat(st ta[], int n); //给结构数组设置初值void Hannuota(st ta[], long max); //移动汉诺塔的主要函数int main(void){int n;cin >> n; //输入圆盘的个数st ta[3]; //三根柱子的信息用结构数组存储Creat(ta, n); //给结构数组设置初值long max = Pow(2, n) - 1;//动的次数应等于2^n - 1 Hannuota(ta, max);//移动汉诺塔的主要函数system(“pause”);return 0;}void Creat(st ta[], int n){ta[0].name = …A‟;ta[0].top = n-1;//把所有的圆盘按从大到小的顺序放在柱子A上for (int i=0; i<n; i++)ta[0].s[i] = n - i;//柱子B,C上开始没有没有圆盘ta[1].top = ta[2].top = 0;for (int i=0; i<n; i++)ta[1].s[i] = ta[2].s[i] = 0;//若n为偶数,按顺时针方向依次摆放 A B Cif (n%2 == 0){ta[1].name = …B‟;ta[2].name = …C‟;}else//若n为奇数,按顺时针方向依次摆放 A C B{ta[1].name = …C‟;ta[2].name = …B‟;}}long Pow(int x, int y){long sum = 1;for (int i=0; i<y; i++)sum *= x;return sum;}void Hannuota(st ta[], long max){int k = 0; //累计移动的次数int i = 0;int ch;while (k < max){//按顺时针方向把圆盘1从现在的柱子移动到下一根柱子ch = ta[i%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << “: “ <<“Move disk “ << ch << ” from “ << ta[i%3].name <<” to “ << ta[(i+1)%3].name << endl;i++;//把另外两根柱子上可以移动的圆盘移动到新的柱子上if (k < max){//把非空柱子上的圆盘移动到空柱子上,当两根柱子都为空时,移动较小的圆盘if (ta[(i+1)%3].Top() == 0 ||ta[(i-1)%3].Top() > 0 &&ta[(i+1)%3].Top() > ta[(i-1)%3].Top()){ch = ta[(i-1)%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << “: “ << “Move disk “<< ch << ” from “ << ta[(i-1)%3].name<< ” to “ << ta[(i+1)%3].name << endl;}else{ch = ta[(i+1)%3].Pop();ta[(i-1)%3].Push(ch);cout << ++k << “: “ << “Move disk “<< ch << ” from “ << ta[(i+1)%3].name<< ” to “ << ta[(i-1)%3].name << endl;}}}}。

递归函数汉诺塔

递归函数汉诺塔

递归函数汉诺塔汉诺塔问题是一个经典的递归问题,最早出现在法国数学家爱德华·卢卡斯的《算数游戏的问题》一书中。

这个问题由三根柱子和一些不同大小的圆盘组成,开始时,所有的盘子都按照大小顺序从小到大叠放在柱子A上,目标是将所有的盘子按照同样的顺序移到柱子C上,期间可以借助柱子B进行临时存放,但要满足以下条件:1.每次只能移动一个盘子;2.大盘子不能放在小盘子上面。

递归的思想是将大问题分解成小问题进行解决。

对于汉诺塔问题,我们可以将它拆分为三个子问题:1.将前n-1个盘子从柱子A移动到柱子B;2.将第n个盘子从柱子A移动到柱子C;3.将前n-1个盘子从柱子B移动到柱子C。

根据上述思路,我们可以设计一个递归函数来解决汉诺塔问题。

以下是一个Python实现的示例代码:```pythondef hanoi(n, source, target, auxiliary):if n > 0:# 将前n-1个盘子从source移动到auxiliaryhanoi(n-1, source, auxiliary, target)# 将第n个盘子从source移动到targetprint("Move disk", n, "from", source, "to", target)# 将前n-1个盘子从auxiliary移动到targethanoi(n-1, auxiliary, target, source)#测试函数hanoi(3, 'A', 'C', 'B')```输出结果为:```Move disk 1 from A to CMove disk 2 from A to BMove disk 1 from C to BMove disk 3 from A to CMove disk 1 from B to AMove disk 2 from B to CMove disk 1 from A to C```以上代码实现了一个递归的汉诺塔函数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

问题提出:
设有三个塔柱(分别为A号,B号和C号)。

初始时,有n 个圆盘按自下向上、从大到小的次序叠置在A 塔上。

现要将A 塔上的所有圆盘,借助于B塔,全部移动到C塔上,且仍按照原来的次序叠置。

移动的规则如下:这些圆形盘只能在个塔间进行移动,一次只能移动一个盘子,且任何时候都不允许将较大的盘子压在比它小的盘子的上面。

要求如下:从键盘输入初始圆形盘子个数n,用C 语言实现n 个盘子最佳移动的全过程[1]。

本题的目的是设计一个盘子移动的方案,使得A 号塔上的所有盘子借助于B塔按照原来的次序移动到C塔上,并且,要给出完整的盘子移动的方案。

下面我们从递归和非递归两种方面进行考虑[2]。

递归解法及其C++实现
1. 当仅有1个盘子时,把这个盘子从A塔柱移动到C塔柱上
2. 当圆盘的个数多于1个时,如下解决:
(1)先将A塔柱上的(n-1)个圆盘通过C塔柱移动到B塔柱上
(2)再将A塔柱上的第n个圆盘直接移动到C塔柱上
(3)最后B塔柱上的(n-1)个圆盘通过A塔柱移动到C塔柱上
//递归算法求解汉诺塔问题2013年5月5日22:36:31
#include <iostream>
//A为放盘子的珠子,B为中间柱子,C为目标柱子
using namespace std;
void hanoi(int n,char a,char b,char c)
{
if(n==1)
{
cout<<"把"<<n<<"号盘子从"<<a<<"->"<<c<<endl;
}
else
{
hanoi(n-1,a,c,b);
cout<<"把"<<n<<"号盘子从"<<a<<"->"<<c<<endl;
hanoi(n-1,b,a,c);
}
}
int main()
{
int n;
cout<<"请输入汉诺塔问题规模:";
cin>>n;
char A='a';
char B='b';
char C='c';
hanoi(n,A,B,C);
return 0;
}。

相关文档
最新文档