汉诺塔(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;}。
c语言汉诺塔
c语言汉诺塔C语言汉诺塔是一种计算机程序的流行示例,可以帮助人们了解编程语言实际运用。
汉诺塔游戏(Tower of Hanoi)也称之为“河内塔”,它是1883年由法国数学家 Edouard Lucas 发明的,是一个递归问题,代表着如何使用有限的步骤或操作来解决更大的问题。
汉诺塔游戏规则是:1. 三根柱子上各放置碟片,碟片从大到小放置,上面碟片小于下面碟片。
2. 要求一次只能移动一个碟片,小碟片只能放在大碟片的上面。
3. 把所有的碟片从一根柱子移动到另一根柱子上去。
C语言汉诺塔程序的基本思想是:以左、中、右三根柱子为基础,将碟片从左到右的柱子上移走,并且只能按照大碟片在下小碟片在上的原则,将其移动到另一端。
汉诺塔运行程序的核心要点是递归,即将一个大问题逐步分解成更小的子问题,并将子问题一步步解决,直到最终解决整个大问题为止。
C语言汉诺塔程序的步骤:1. 首先,要设计一个函数,该函数需要传入三个参数,分别是:圆盘数量N、源杆A作为起始位置,目标杆C作为目标位置,辅助杆B 作为过渡杆。
2. 接着,在设计函数的内部通过if...else结构判断:如果要移动的碟片数量只有1个,则直接把碟片从源杆A移动到目标杆C;否则,就要执行更复杂的操作,首先将N-1个碟片从源杆A移动到辅助杆B,接着将第N个碟片从源杆A移动到目标杆C,最后将N-1个碟片从辅助杆B移动到目标杆C,整个过程重复执行,直到所有的碟片都移动完成。
3. 最后,在主函数中调用上述汉诺塔函数,并输出完整的移动步骤。
C语言汉诺塔程序的实现过程很容易理解,它的核心就是利用递归的方法进行解决问题,这表明它是一种有效的解决方案,可以把复杂问题拆解成更小的子问题,一步步解决整个问题,这样可以避免汉诺塔中复杂繁琐的操作,更重要的是,一旦发现问题出现差错,可以及时纠正。
C语言实现汉诺塔(图文详解)
C语⾔实现汉诺塔(图⽂详解)⽬录思路:当n=1时:当n=2时:当n=3时:当n=4时:见代码运⾏截图总结汉诺塔的游戏规则:有三根⾦刚⽯柱⼦A、B、C,在A柱⼦上从下往上按照⼤⼩依次减⼩的顺序摞着64⽚黄⾦环。
⼤梵天命令婆罗门把环从下⾯开始按⼤⼩顺序重新摆放在另⼀根柱⼦上。
并且规定,在任何⼀个柱⼦上,⼩环上不能放⼤环,在三根柱⼦之间⼀次只能移动⼀个环。
即将A柱⼦上全部的环通过中间柱⼦B(B柱⼦作为中介)移动到C柱⼦上当A只有⼀个环的时候:A->C当A只有两个环的时候:A->B A->C B->C当A只有三个环的时候:A->C A->B C->B A->C B->A B->C A->C思路:1、将 n-1个环先放到B柱⼦上2、将A柱⼦上的最后⼀个环移动到C柱⼦上3、将n-1个环从B柱⼦移动到C柱⼦上当n=1时:1、将0个环先放到B柱⼦上2、将A柱⼦上的最后⼀个环移动到C柱⼦上:A->C3、将0个环从B柱⼦移动到C柱⼦上当n=2时:1、将1个环先放到B柱⼦上:A->B2、将A柱⼦上的最后⼀个环移动到C柱⼦上:A->C3、将1个环从B柱⼦移动到C柱⼦上:B->C当n=3时:1、将2个环先放到B柱⼦上:使⽤递归将2个环放到B上,因为A柱⼦的最后⼀个环是最⼤的因此可以先不理会,递归重复当n=2时的步骤,不过是从将2个环从A放到C上改为将2个环从A放到B上了2、将A柱⼦上的最后⼀个环移动到C柱⼦上:A->C3、将2个环从B柱⼦移动到C柱⼦上:使⽤递归将2个环从B柱⼦移动到C柱⼦上,此时C柱⼦上已经有了最⼤的⼀个环因此可以不⽤再理会了,递归重复当n=2的步骤,不过是从将2个环从A放到C上改为将2个环从B放到C上了当n=4时:1、将3个环先放到B柱⼦上:递归重复n=3的步骤,不过是从将3个环从A放到C上改为将3个环从A放到B上了2、将A柱⼦上的最后⼀个环移动到C柱⼦上:A->C3、将3个环从B柱⼦移动到C柱⼦上:递归重复当n=3的步骤,不过是从将3个环从A放到C上改为将3个环从B放到C上了见代码#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>void move(char X, char Y){printf("%c->%c ", X, Y);}void HanoiTower(int n, char A, char B, char C){if (n == 1)//递归终⽌条件{move(A, C);return;}else{HanoiTower(n - 1, A, C, B);//将n-1个环从A柱⼦放到B柱⼦上,C柱⼦作为中介move(A, C);//将A柱⼦上的最后⼀个环移动到C柱⼦上HanoiTower(n - 1, B, A, C);//将n-1个环从B柱⼦放到C柱⼦上,A柱⼦作为中介}}int main(){printf("请确认A柱⼦上⼀共有多少个环:\n");int n = 0;scanf("%d", &n);HanoiTower(n, 'A','B','C');//将n个环从A柱⼦放到C柱⼦上,B柱⼦作为中介}运⾏截图总结本篇⽂章就到这⾥了,希望能给你带来帮助,也希望您能够多多关注的更多内容!。
c语言例题10-5 汉诺(hanoi)塔问题
汉诺塔问题是一个经典的递归问题。
在汉诺塔问题中,有三根柱子,第一根柱子上从下到上放着n 个盘子,目标是将这些盘子从第一根柱子移动到第三根柱子上,并且只能每次移动一个盘子,并且不能将一个较大的盘子放在较小的盘子上面。
以下是一个使用 C 语言实现的汉诺塔问题的示例代码:```c#include <stdio.h>void hanoi(int n, char A, char B, char C) {if (n == 1) {printf("Move disk 1 from %c to %c\n", A, C);return;}hanoi(n - 1, A, C, B);printf("Move disk %d from %c to %c\n", n, A, C);hanoi(n - 1, B, A, C);}int main() {int n = 3; // 盘子数量hanoi(n, 'A', 'B', 'C'); // 调用递归函数,将盘子从A 柱子移动到 C 柱子,B 柱子作为辅助柱子return 0;}```在这个代码中,我们定义了一个`hanoi` 函数来递归地解决汉诺塔问题。
在`hanoi` 函数中,我们首先检查盘子数量是否为1,如果是,则直接将盘子从起始柱子移动到目标柱子。
否则,我们使用两个辅助柱子来将n-1 个盘子从起始柱子移动到第二个辅助柱子上,然后将最后一个盘子从起始柱子移动到目标柱子上,最后再将n-1 个盘子从第二个辅助柱子移动到目标柱子上。
在`main` 函数中,我们定义了盘子数量n,并调用了`hanoi` 函数来解决问题。
C语言程序设计课程设计报告---汉诺塔问题
XXXX大学计算机科学与技术学院课程设计报告2012 — 2013学年第一学期课程名称C/C++高级语言程序设计课程设计设计题目小游戏和图形处理汉诺塔问题学生姓名XXX学号XXXXXXX专业班级XXXXXXXXXXX指导教师XX2012 年X 月XX 日目录一、课程设计问题描述 (1)1、课程设计题目 (1)2、设计任务要求 (1)二、总体设计 (1)1、设计思路 (1)2、汉诺塔求解流程图 (2)三、详细设计 (2)1、汉诺塔问题描述 (2)2、算法分析 (3)3、实现递归的条件 (4)4、用C语言实现 (4)四、程序运行结果测试与分析 (4)1、打开Microsoft Visual C++ 6.0操作平台输入以下的源代码 (4)2、编译源代码 (5)3、组建 (5)4、执行 (5)5、运行结果 (6)6、按任意键结束程序 (7)五、结论与心得 (7)六、参考文献 (8)七、附录:程序源代码 (8)一、课程设计问题描述1、课程设计题目汉诺塔问题2、设计任务要求输入盘子数(2个以上有效),移动速度,开始演示汉诺塔移动的步骤,要求:盘子A,B,C柱需要自己绘制,初始时盘子在A柱上通过B柱最终移动到C 柱上,显示出盘子在几个柱之间的移动过程。
二、总体设计1、设计思路对于一个类似的这样的问题,任何一个人都不可能直接写出移动盘子的每一个具体步骤。
可以利用这样的统筹管理的办法求解:我们假设把该任务交给一个僧人,为了方便叙述,将他编号为64。
僧人自然会这样想:假如有另外一个僧人能有办法将63个盘子从一个座移到另一个座,那么问题就解决了,此时僧人A B C64只需这样做:(1).命令僧人63将63个盘子从A座移到C座(2).自己将最底下的最大的一个盘子从A座移到C座(3).再命令僧人63将63个盘子从B座移到C座为了解决将63个盘子从A座移到B座的问题,僧人63又想:如果能再有一个僧人62能将62个盘子移动到另一座,我就能将63个盘子从A座移动到B座。
汉诺塔c课程设计
汉诺塔c 课程设计一、教学目标本课程的学习目标包括:知识目标:学生能理解汉诺塔问题的定义、解法及其应用;掌握汉诺塔问题的算法思想和编程方法。
技能目标:学生能够运用汉诺塔问题的解法解决实际问题,提高逻辑思维和问题解决能力;学会使用编程语言实现汉诺塔问题的算法。
情感态度价值观目标:学生培养对计算机科学的兴趣,增强创新意识和团队协作精神,认识汉诺塔问题在现实生活中的重要性。
二、教学内容教学内容主要包括:1.汉诺塔问题的定义和背景;2.汉诺塔问题的解法及其证明;3.汉诺塔问题的算法分析;4.汉诺塔问题的编程实现;5.汉诺塔问题在现实生活中的应用。
三、教学方法本课程采用多种教学方法,包括:1.讲授法:讲解汉诺塔问题的定义、解法、算法和应用;2.讨论法:引导学生探讨汉诺塔问题的解决策略,培养团队协作能力;3.案例分析法:分析现实生活中的汉诺塔问题实例,提高学生的问题解决能力;4.实验法:让学生动手编程实现汉诺塔问题,培养实践操作能力。
四、教学资源教学资源包括:1.教材:选用权威、实用的汉诺塔问题教材,为学生提供理论基础;2.参考书:提供相关领域的参考书籍,丰富学生的知识体系;3.多媒体资料:制作课件、视频等多媒体资料,增强课堂教学的趣味性;4.实验设备:配置合适的计算机设备,确保学生能够顺利进行编程实践。
五、教学评估教学评估主要包括:1.平时表现:评估学生在课堂上的参与度、提问回答等情况,占比20%;2.作业:评估学生完成作业的质量和效率,占比30%;3.考试:定期进行汉诺塔问题相关知识的考试,占比50%。
评估方式应客观、公正,能够全面反映学生的学习成果。
六、教学安排教学安排如下:1.教学进度:按照教材和教学大纲进行教学,确保完成所有教学内容;2.教学时间:每周安排2课时,共10周;3.教学地点:教室。
教学安排应合理、紧凑,确保在有限的时间内完成教学任务,同时考虑学生的实际情况和需要。
七、差异化教学根据学生的不同学习风格、兴趣和能力水平,设计差异化的教学活动和评估方式,以满足不同学生的学习需求。
c语言汉诺塔编程题试题库及答案
c语言汉诺塔编程题试题库及答案C语言汉诺塔编程题试题库及答案一、试题1. 请编写一个C语言程序,实现汉诺塔问题的解决方案。
2. 程序需要接受用户输入的盘子数量,然后输出移动盘子的完整步骤。
3. 要求使用递归函数来解决汉诺塔问题。
二、答案```c#include <stdio.h>// 递归函数,用于移动盘子void hanoi(int n, char from_rod, char to_rod, char aux_rod) { if (n == 1) {printf("\n 移动盘子 1 从 %c 到 %c", from_rod, to_rod); return;}hanoi(n - 1, from_rod, aux_rod, to_rod);printf("\n 移动盘子 %d 从 %c 到 %c", n, from_rod, to_rod); hanoi(n - 1, aux_rod, to_rod, from_rod);}// 主函数int main() {int n;printf("输入盘子的数量: ");scanf("%d", &n);// 调用递归函数开始解决汉诺塔问题hanoi(n, 'A', 'C', 'B'); // A为起始柱子,C为目标柱子,B为辅助柱子return 0;}```三、解析1. 程序首先包含了标准输入输出头文件`stdio.h`。
2. `hanoi`函数是一个递归函数,它接受四个参数:盘子数量`n`,起始柱子标识符`from_rod`,目标柱子标识符`to_rod`,以及辅助柱子标识符`aux_rod`。
3. 如果只有一个盘子,直接将其从起始柱子移动到目标柱子。
4. 如果有多于一个盘子,先将上面的`n-1`个盘子从起始柱子借助目标柱子移动到辅助柱子。
c课程设计汉诺塔
c 课程设计汉诺塔一、教学目标本课程的教学目标是让学生掌握汉诺塔问题的解法及其背后的数学原理,培养学生的逻辑思维能力和解决问题的能力。
具体分为三个维度:1.知识目标:学生能理解汉诺塔问题的定义,掌握递归算法解决汉诺塔问题的方法,了解汉诺塔问题在计算机科学中的应用。
2.技能目标:学生能运用递归算法独立解决较小规模的汉诺塔问题,能阅读并理解相关的代码实现,能对代码进行调试和优化。
3.情感态度价值观目标:学生在解决汉诺塔问题的过程中,培养耐心、细致的思维习惯,感受数学与计算机科学的魅力,增强对编程学习的兴趣。
二、教学内容本课程的教学内容主要包括以下几个部分:1.汉诺塔问题的引入:介绍汉诺塔问题的定义,通过生活中的实例让学生感受汉诺塔问题,引导学生思考如何解决汉诺塔问题。
2.递归算法的讲解:讲解递归算法的基本原理,如何运用递归算法解决汉诺塔问题,并通过代码实现汉诺塔问题的解决。
3.汉诺塔问题的拓展:引导学生思考汉诺塔问题在计算机科学中的应用,如排序算法等,让学生了解汉诺塔问题在实际生活中的意义。
4.编程实践:让学生通过编写代码,独立解决汉诺塔问题,培养学生的编程能力和解决问题的能力。
三、教学方法本课程的教学方法采用讲授法、讨论法和实验法相结合的方式,具体如下:1.讲授法:教师通过讲解汉诺塔问题的定义、递归算法的原理等,使学生掌握相关的理论知识。
2.讨论法:教师学生进行小组讨论,引导学生思考汉诺塔问题的解决方法,培养学生的逻辑思维能力。
3.实验法:教师引导学生通过编写代码,解决汉诺塔问题,培养学生的实际操作能力和编程能力。
四、教学资源本课程的教学资源主要包括教材、参考书、多媒体资料和实验设备等,具体如下:1.教材:选用与汉诺塔问题相关的教材,为学生提供系统的理论知识学习。
2.参考书:提供相关的参考书目,丰富学生的知识视野。
3.多媒体资料:制作相关的教学课件、视频等,以生动形象的方式展示汉诺塔问题的解法。
4.实验设备:为学生提供必要的计算机设备,让学生能够进行实际的编程操作。
c语言程序汉诺塔优秀教学设计
c语言程序汉诺塔优秀教学设计C语言程序汉诺塔优秀教学设计引言:汉诺塔是一个经典的数学谜题,也是计算机科学中的经典算法之一。
通过教学学生编写C语言程序实现汉诺塔问题,可以锻炼学生的逻辑思维能力、编程能力和解决问题的能力。
本文将提供一套优秀的教学设计,一步一步引导学生完成汉诺塔程序的编写。
一、理解汉诺塔问题首先,我们需要向学生介绍汉诺塔问题的背景和规则。
给定三个柱子A、B和C,其中柱子A上有多个大小不等的圆盘,我们的目标是将所有的圆盘从A柱子上移动到C柱子上,并且保证移动过程中大圆盘不会放在小圆盘上。
二、解答汉诺塔问题的思路1. 观察问题首先,我们可以让学生观察当圆盘数量为1、2、3的时候,问题的解决方法,以帮助他们理解问题规律。
2. 分解问题然后,我们引导学生发现,并分解出一个子问题:如何将n-1个圆盘从A柱子通过B柱子移动到C柱子。
这一步是解决该问题的关键,也是递归思想的应用。
3. 递归思想我们通过递归思想解决子问题:将n-1个圆盘从A柱子通过B柱子移动到C柱子。
递归的停止条件是当圆盘数量为1时,直接将其从A柱子移动到C柱子。
4. 移动圆盘接下来是具体的移动圆盘的操作。
我们可以定义一个函数move(),通过将圆盘从一个柱子移动到另一个柱子来实现。
该函数应该接受三个参数:源柱子、目标柱子和经由的柱子。
我们通过调用该函数来实现圆盘的移动。
三、实现C语言汉诺塔程序在介绍完解题思路后,我们引导学生一步一步实现C语言的汉诺塔程序。
1. 定义函数move()首先,我们可以引导学生定义一个函数move(),该函数接受三个参数:源柱子、目标柱子和经由的柱子。
例如,函数定义可以如下所示:void move(char from, char to, char via);2. 实现递归停止条件然后,我们引导学生实现递归停止条件。
当圆盘数量为1时,我们将其从源柱子移动到目标柱子。
例如,可以使用如下语句实现:if(n == 1){printf("Move disk from c to c\n", from, to);return;}3. 递归调用move()函数接下来,我们需要在递归的情况下调用move()函数。
c课程设计汉诺塔
c 课程设计汉诺塔一、教学目标本课程的教学目标是让学生掌握汉诺塔的基本概念、原理和解决方法,培养学生的逻辑思维能力和问题解决能力。
具体来说,知识目标包括了解汉诺塔的历史背景、基本规则和递归算法;技能目标包括能够运用递归算法解决汉诺塔问题,并进行简单的优化;情感态度价值观目标包括培养学生的团队合作意识、挑战自我和探索未知的勇气。
二、教学内容教学内容主要包括汉诺塔的基本概念、递归算法的原理和应用。
首先,介绍汉诺塔的历史背景和基本规则,让学生了解汉诺塔的起源和演变。
然后,讲解递归算法的原理,引导学生理解递归的思维方式和实现方法。
最后,通过实例分析,让学生学会如何运用递归算法解决汉诺塔问题,并进行简单的优化。
三、教学方法为了激发学生的学习兴趣和主动性,本课程将采用多种教学方法。
首先,运用讲授法,清晰地传达汉诺塔的基本概念和递归算法的原理。
其次,通过讨论法,让学生在课堂上相互交流、分享心得,培养学生的团队合作意识。
此外,结合案例分析法,让学生通过分析实际问题,提高问题解决能力。
最后,运用实验法,让学生动手实践,加深对汉诺塔解决方法的理解。
四、教学资源为了支持教学内容和教学方法的实施,我们将选择和准备适当的教学资源。
教材方面,将选用权威、实用的汉诺塔教材,确保学生掌握准确的知识。
参考书方面,将推荐一些经典的汉诺塔相关书籍,拓展学生的知识视野。
多媒体资料方面,将收集一些关于汉诺塔的动画、视频等资料,丰富学生的学习体验。
实验设备方面,将准备相应的设备,让学生进行实践活动,提高操作技能。
五、教学评估本课程的评估方式包括平时表现、作业和考试三个部分。
平时表现主要评估学生在课堂上的参与程度、提问回答和团队协作等情况,占总评的30%。
作业分为练习题和项目任务,主要评估学生对知识的理解和应用能力,占总评的40%。
考试为闭卷笔试,涵盖课程全部内容,主要评估学生的知识掌握和问题解决能力,占总评的30%。
评估方式客观、公正,全面反映学生的学习成果。
C语言递归调用实例——汉诺塔问题动画实现(附完整代码)
二、程序框架
古人云,不谋全局者,不足谋一域。同样,在编写代码之前,我们必 须得有个大体的思路和整体上的把握。不能一上来就稀里糊涂地乱敲一通。 当然,这里我也只能仅仅谈自己的个人想法,不一定就是最优的解决方案, 还希望能和大家一起相互交流,共同进步。整个程序的框架,我把它分为 动画效果和核心算法两大部分。我首先实现的是动画效果部分,等能够实 现盘子的随意移动后,我才开始研究核心算法的实现。这样一来,在核心 算法部分,我们正好可以利用前面的动画效果来直观地反映出我们的思路, 有助于代码的调试和缩短程序的开发周期。为了尽量减少废话,我们可以 用一张图来进行表示:
图 1-1 移动第一个圆盘..................................................................................................................... 4 图 1-2 移动第二个圆盘...................................................................................................................... 5 图 1-3 移动最后一个圆盘................................................................................................................. 6
能移动一个圆盘,且圆盘在放到棒上时,大的不能放在小的上面。中间的一根
棒作为辅助移动用。” 事实上,对此曾经有人作过分析,按这个规则,众僧耗尽毕生精力也
不可能完成圆盘的移动,因为需要移动圆盘的次数是一个天文数字 18446744073709551615(64 个圆盘需要移动的次数为 2 的 64 次方)。假设 1us 进行一次移动,也需要约一百万年的时间,使用计算机也很难解决 64
汉诺(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.从上⾯分析可以看出:只有等后⾯那个和尚搬完盘⼦,前⾯的和尚才能够去完成任。
让我们来栈的数据结构:数据的处理只在⼀端处理,且是先进后出。
所以⽤递归的⽅法去处理是正确的。
(汉诺塔图)
汉诺塔问题解决⽅案
如果你发现有什么错误之处,请指出!谢谢了。
汉诺塔c语言程序代码
汉诺塔c语言程序代码(通过vc++6.0验证)(附讲解)让我们先看看代码吧#include <stdio.h>int hj(int a,int b, int c,int i){int t;if(i==1)printf("%d->%d\n",a,c);else{t=c;c=b;b=t;hj(a,b,c,i-1);printf("%d->%d\n",a,b);t=a;a=c;c=t;t=b;b=c;c=t;hj(a,b,c,i-1);return 0;}}main(){int a,b,c,i;a=1;b=2;c=3;printf("请输入汉诺塔的盘数");scanf("%d",&i);hj(a,b,c,i);return 0;}以上是汉诺塔的代码,该程序主要是运用了递归的思想,比如数学中的f(x)=f(x-1)+f(x-2),在本程序中为:int hj(int a,int b, int c,int i){int t;if(i==1)printf("%d->%d\n",a,c);else{t=c;c=b;b=t;hj(a,b,c,i-1);也就是说,我们在这个函数中再次调用这个函数,相当于一个循环,而在再次调用的过程中,i的值变成i-1,就类似于f(x-1),这样层层调用,最终就变成当i=1的时候的值,然后通过运算,计算出想要得到的值。
汉诺塔的数值分析:我们可以发现,当只有一个盘的时候,我们只需要做1->3(就是把第一个柱子上的最顶端的盘移动到第三根柱子,以下不再解释)当有两个盘的时候,是1->2 1->3 2->3三个盘子是:1->3 1->2 3->2 1->3 2->1 2->3 1->3分析一下可以得出以下结论:初始值a=1 b=2 c=3一个盘子就是a->c两个盘子与一个盘子的关系是:第一步:b与c交换值,然后打印a->c第二步:打印a->b第三步:a与c交换值,b与c交换值,打印a->c进一步分析,便可以得出以下结论只要盘子数量为i(i大于1),那么它就有三部分第一部分,b与c交换值,然后运行i-1第二部分,打印a->b第三部分,a与c交换值,b与c交换值,然后运行i-1程序表示便是:if(i==1)printf("%d->%d\n",a,c);else{t=c;c=b;(交换值)b=t;hj(a,b,c,i-1);printf("%d->%d\n",a,b);t=a;a=c;c=t;(a c交换)t=b;b=c;c=t;(b c交换)hj(a,b,c,i-1);。
汉诺塔问题的程序实现(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<。
汉诺塔c语言讲解
汉诺塔c语言讲解
汉诺塔是一种经典的数学逻辑游戏,同时也是计算机科学中经典的递归算法示例之一。
在汉诺塔游戏中,我们有三个柱子,最初第一个柱子上排列着n个圆盘,它们呈金字塔形状。
我们的任务是把这些盘子一个一个地从第一个柱子移到第三个柱子上,同时保持它们原来的顺序。
C语言是一种流行的编程语言,它可以用来实现各种算法和游戏。
用C语言实现汉诺塔游戏就非常简单。
我们可以将汉诺塔的规则抽象为下面这段C语言代码:
void hanoi(int n, char a, char b, char c)
{
if (n == 1) {
printf("%c to %c\n", a, c);
} else {
hanoi(n-1, a, c, b);
printf("%c to %c\n", a, c);
hanoi(n-1, b, a, c);
}
}
这个函数接受四个参数,分别是表示盘子数目的n,以及三个柱子的标识符a、b和c。
它通过递归实现将n个盘子从a柱子移动到c柱子的过程。
每次调用hanoi()函数时,它都会将一个盘子从a柱子上取下,然后递归地将n-1个盘子从a移到b柱子上,最后将那个盘子从a 移到c柱子上。
这个算法非常简洁和优美,同时也能展示出递归算法的良好性质。
总之,用C语言实现汉诺塔游戏是一种非常有趣和有益的编程练习,可以提高我们的编程能力和算法思维水平。
C语言汉诺塔问题,用C语言实现汉诺塔
C语言汉诺塔问题,用C语言实现汉诺塔汉诺塔问题是指:一块板上有三根针A、B、C。
A 针上套有64 个大小不等的圆盘,按照大的在下、小的在上的顺序排列,要把这64 个圆盘从A 针移动到C 针上,每次只能移动一个圆盘,移动过程可以借助B 针。
但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。
从键盘输入需移动的圆盘个数,给出移动的过程。
算法思想对于汉诺塔问题,当只移动一个圆盘时,直接将圆盘从A 针移动到C 针。
若移动的圆盘为n(n>1),则分成几步走:把(n-1) 个圆盘从A 针移动到B 针(借助C 针);A 针上的最后一个圆盘移动到C 针;B 针上的(n-1) 个圆盘移动到C 针(借助A 针)。
每做一遍,移动的圆盘少一个,逐次递减,最后当n 为1 时,完成整个移动过程。
因此,解决汉诺塔问题可设计一个递归函数,利用递归实现圆盘的整个移动过程,问题的解决过程是对实际操作的模拟。
程序代码1.#include<stdio.h>2.int main()3.{4.int hanoi(int,char,char,char);5.int n,counter;6.printf("Input the number of diskes:");7.scanf("%d",&n);8.printf("\n");9. counter=hanoi(n,'A','B','C');10.return0;11.}12.13.int hanoi(int n,char x,char y,char z)14.{15.int move(char,int,char);16.if(n==1)17.move(x,1,z);18.else19.{20.hanoi(n-1,x,z,y);21.move(x,n,z);22.hanoi(n-1,y,x,z);23.}24.return0;25.}26.27.int move(char getone,int n,char putone)28.{29.static int k=1;30.printf("%2d:%3d # %c---%c\n",k,n,getone,putone);31.if(k++%3==0)32.printf("\n");33.return0;34.}调试运行结果当移动圆盘个数为3 时,具体移动步骤如下所示:。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
bar(160, 540, 240, 580);
setfont(30, 0, "黑体");
++s[0].top;//进栈
for (int i1 = 0; i1 < 4; i1++)
{
p[i]->a[i1] = ta[i1];
s[0].stack[s[0].top] = p[i];//记录每个矩形的位置,top为圆盘的个数
}
}
Hannoi(n, 'a', 'b', 'c');//汉诺塔递归函数
//绘制运动画面的的环境
setcolor(RED);
//三根红色线段作为钢针
line(400, 110, 400, 500);
line(600, 110, 600, 500);
line(200, 110, 200, 500);
//长方体形的底座
setfillstyle(LIGHTGRAY);
bar3d(80, 500, 720, 510, 10, true);
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#define MAX 64//圆盘的最大数目
#define NULL 0
//定义栈
struct STKNODE
{
int a[4];
};
struct STK
{
STKNODE*stack[MAX];
inttop;
};
//定义全局变量
STK s[3];//声明三个栈,分别代表一号二号三号钢针上圆盘的状态
int v = 5;//调整速度
int num=0;//记录总共移动次数
//函数声明
void Initstk(STK* s);//初始化栈
void Hannoi(int n, char a, char b, char c);//汉诺塔递归
}
//向下
while (b<=610)
{
setfillstyle(RED);
bar(a, b, a + 10, b + 20);
Sleep(10);
setfillstyle(WHITE - b);
bar(a, b, a + 10, b + 20);
b += 10;
}
if (kbhit())
{
break;
while (a <= 760)
{
setfillstyle(YELLOW);
bar(a, b, a + 10, b + 20);
Sleep(10);
setfillstyle(WHITE + a);
bar(a, b, a + 10, b + 20);
a += 10;
}
if (kbhit())
{
break;
adjust();//调整函数
Sleep(10 * v);//暂停(ms)
setfillstyle(WHITE);
bar(q0->a[0], q0->a[1], q0->a[2], q0->a[3]);
setcolor(RED);
line((q0->a[0] + q0->a[2]) / 2, q0->a[1], (q0->a[0] + q0->a[2]) / 2, q0->a[3]);//重新画上被擦掉原有的红线
q0->a[1] -= 10;
q0->a[3] -= 10;
if (s[i4].top == 0)//重新画上最后一个矩形块擦掉的底座上的两条红线
{
line(110 + i4 * 200, 500, 290 + i4 * 200, 500);
line(110 + i4 * 200, 493, 290 + i4 * 200, 493);
}
//向上
while (b >= 40)
{
setfillstyle(BLUE);
bar(a, b, a + 10, b + 20);
Sleep(10);
setfillstyle(WHITE + b);
bar(a, b, a + 10, b + 20);
b -= 10;
}
}
//清空开始界面
cleardevice();
{
if(n == 1)
Move(1, a, c);
else
{
Hannoi(n-1, a, c, b);
Move(n, a, c);
Hannoi(n-1, b, a, c);
}
}
//栈的初始化
void Initstk(STK *s)
{
int i;
s->top = 0;
for (i = 0; i <= MAX; i++)
while (q0->a[3] <= q1->a[3])
{
setfillstyle(YELLOW);
bar(q0->a[0], q0->a[1], q0->a[2], q0->a[3]);
adjust();
Sleep(10 * v);
setfillstyle(WHITE);
bar(q0->a[0], q0->a[1], q0->a[2], q0->a[3]);
汉诺塔
能给出盘子具体移动的移动过程及完成整个移动所需要的总次数,也可以以图形界面展示移动过程。
完整代码如下:
---------------------------------------------------------------------------------------------------------------------------------
//源栈与目的栈值的传递
q0 = s[i4].stack[s[i4].top];
++s[i5].top;//进栈
q1->a[0] = q0->a[0] + i3 * 200;
q1->a[1] = 500 - s[i5].top * 20;
q1->a[2] = q0->a[2] + i3 * 200;
}
//向左
while (a >= 40)
{
setfillstyle(GREEN);
bar(a, b, a + 10, b + 20);
Sleep(10);
setfillstyle(WHITE - a);
bar(a, b, a + 10, b + 20);
a -= 10;
}
if (kbhit())
{
break;
i4 = switchab(a);//源钢针钢针号
i5 = switchab(b);//目的钢针号
STKNODE *q1, *q0;//两个中间结点用于源栈和目的栈间的值得传递,q1为目的栈,q0为源栈
q1 = (STKNODE *)malloc(sizeof(STKNODE));
q0 = (STKNODE *)malloc(sizeof(STKNODE));
//setfillstyle(YELLOW);//圆盘的颜色
for (int i=0; i < n; i++)
{
ta[0] += 5;
ta[1] -= 20;
ta[2] -= 5;
ta[3] -= 20;
//bar(ta[0], ta[1], ta[2], ta[3]);//画出n个从大到小一次叠放的黄色圆盘
for (int i2 = 0; i2 < n; i2 ++)
{
p[i2] = (STKNODE *)malloc(sizeof(STKNODE));//为每一个指针申请空间
}
Initstk(&s[0]);
Initstk(&s[1]);
Initstk(&s[2]);//将三个栈初始化
//start();//呈现开始画面
void start();//开始画面
void Move(int n, char a, char b);//移动过程
int switchab(char a);//返回钢针号
void adjust();//调整速度暂停
//主函数
void main()
{
int n, ta[4] = {115, 500, 285, 520};//第一个圆盘的位置
}
}
//向左或右运动,与i3的正负有关
while (q0->a[2] != q1->a[2])
{
setfillstyle(YELLOW);
bar(q0->a[0], q0->a[1], q0->a[2], q0->a[3]);
adjust();
Sleep(10 * v);
setfillstyle(WHITE);
setfont(20, 0, "黑体");
setfont(50, 0, "黑体");
setcolor(GREEN);
outtextxy(200, 350, "随便按一个键开始吧!");