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.技能目标:培养学生运用C语言实现汉诺塔问题的解决方案,提高编程实践能力。
3.情感态度价值观目标:培养学生独立思考、合作交流的学习习惯,增强对计算机科学的兴趣和热情。
二、教学内容本节课的教学内容主要包括以下几个部分:1.汉诺塔问题的定义和解法:介绍汉诺塔问题的背景,讲解其解法及步骤。
2.递归算法的原理:讲解递归算法的基本概念、特点及其在解决汉诺塔问题中的应用。
3.C语言实现汉诺塔问题:引导学生运用C语言编写汉诺塔问题的解决方案,并进行调试和优化。
4.算法分析和改进:分析汉诺塔问题的算法复杂度,探讨如何优化算法性能。
三、教学方法为了达到本节课的教学目标,采用以下几种教学方法:1.讲授法:讲解汉诺塔问题的定义、解法和递归算法的原理。
2.案例分析法:分析实际案例,让学生了解递归算法在解决汉诺塔问题中的应用。
3.实验法:引导学生动手实践,用C语言实现汉诺塔问题的解决方案。
4.讨论法:学生进行小组讨论,分享算法优化思路,培养合作交流能力。
四、教学资源本节课的教学资源包括以下几个方面:1.教材:选用《C程序设计》等相关教材,为学生提供理论知识的学习参考。
2.参考书:推荐《算法导论》等参考书籍,帮助学生深入了解算法原理。
3.多媒体资料:制作PPT、教学视频等多媒体资料,辅助学生理解和记忆知识点。
4.实验设备:为学生提供计算机、编程环境等实验设备,方便学生动手实践。
五、教学评估本节课的教学评估主要包括以下几个方面:1.平时表现:评估学生在课堂上的参与度、提问回答等情况,占比20%。
2.作业:评估学生完成的汉诺塔问题相关练习,包括C语言代码编写和调试,占比30%。
用C语言解决汉诺塔问题的方法及过程分析
( )将 原 问题 转化 成 新 问题 后 ,能使 求 解算法 的规模减 小. 2
( )递归 有一 个 明显 的 出 口,或称 为递 归的边 界 ,而边 界 问题 的解是显 而 易见 的或 已知 的. 3
3 用 C语 言 编 程
C语 言是 一种 在 国内外 广泛 流行 的高 级程 序设 计语 言 ,它 的语 言 功能 丰富 ,表达 力 强 ,使 用 灵 活 ,应
言 中 ,用 递归 法编 写 条件
2 1 递 归程序 定义 .
《 C程 序设 计 》 数 据结 构 》等教科 书 中 ,都对 递 归 程 序 给 出 了基本 相 同的定 义 ,归纳 如下 :在调 用 、《
一
个 函数 的过 程 中 ,又直接 或 间接地 调用 了该 函数本 身 ,称 为 函数 的递 归调 用 ,使用 了递 归调用 函数 的程
第 3期
{ a ( 一 , o e t r e t ) hn n1 n , h e , wo ;
mo e ( ne, t e ); v o hr e
h n ( 一 ,t a n 1 wo,o e h e ) ) n ,t r e ;)
ma n ( i )
{n i tn;
prn f ( “ e s nt rt mbe ike ” it Pla e e e he nu rofd s s: );
维普资讯
维普资讯
2 0 年 6月 06
河 北 北 方 学 院学 报 ( 自然 科 学 版 )
第 3 期
上操 作 的实质 是把移 动 n个 盘子 的 问题转 化 为移 动 n 一1个盘 .那 一 、三 步 如何解 决 ?事 实 上 ,上述 方法 设盘 子数 为 n ,n可 为任 意数 ,该 法 同样 适 用于 移动 n 1 盘. 因此 ,依 据 上 法 ,可解 决 n 一 个 一1个 盘子从 A杆 移 到 B杆 ( 一 步)或 从 B杆 移到 C杆 ( 第 第三 步 ) 问题 .现 在 ,问题 由移 动 n个 盘 子 的操 作转 化 为 移动 n 一2个 盘子 的操作 .依 据该 原 理 ,层 层递 推 ,即可将 原 问题 转化 为 解 决移 动 n 、n … …3 、 一2 一3 、2 直 到移动 1 盘 的操 作 ,而移 动一 个 盘 的操 作 是可 以 直接 完成 的. 至 此 ,我 们 的任 务 算作 是 真 正完 成 了. 个 而这 种 由繁化 简 ,用简单 的问题 和 已知 的操 作 运算来 解决 复杂 问题 的方 法 ,就是 递归法 . 在计算 机设计 语
汉诺塔问题(Hanoi)的C++代码实现
汉诺塔问题(Hanoi)的C++代码实现1 #include <iostream>2using namespace std;3//第⼀个塔为初始塔,第⼆个塔为中转塔,第三个塔为⽬标塔45int i = 1; //记录步数6void move(int n,char from,char to) //将编号为N的盘⼦由from塔转移到to塔7{8 cout<<"第"<<i++<<"步:将"<<n<<"号盘⼦"<<from<<"---->"<<to<<endl; //输出实例:第1步:将1号盘⼦A---->C9}1011void hanoi(int n,char from,char denpend_on,char to) //汉诺塔递归函数,参数依次为盘⼦数,起始塔,中转塔,⽬标塔12{13if(n==1)14 {15 move(1,from,to); //当需要移动的盘⼦数为1的时候,将此盘⼦从起始塔直接移动到⽬标塔16 }17else18 {19 hanoi(n-1,from,to,denpend_on); //当需要移动的盘⼦数不为1的时候,20//先将除最下⾯的盘⼦外的盘⼦从起始塔借助⽬标塔移动到中转塔21 move(n,from,to); //将剩下的最后的塔直接从起始塔移动到⽬标塔22 hanoi(n-1,denpend_on,from,to); //将之前移⾛的n-1个盘⼦从中转塔借助起始塔移动⾄⽬标塔23 }24}2526int main()27{28int n = 0;//n为盘⼦数29 cout<<"请输⼊盘⼦的个数:";30 cin>>n;31while(n<=0)//⾮法盘⼦数判断32 {33 cout<<"盘⼦的个数不应⼩于1,请重新输⼊:";34 cin>>n;35 }36if(n>0)37 {38char x='A',y='B',z='C';39 cout<<"盘⼦移动情况如下:"<<endl;40 hanoi(n,x,y,z); //调⽤hanoi函数41return0;42 }43 }运⾏结果:递归实现,未对过程进⾏存储。
C语言常用简单算法
C语言常用简单算法C语言是一种广泛应用的编程语言,支持各种算法的实现。
以下是一些常用的简单算法,涵盖了排序、查找、递归等方面。
1. 冒泡排序(Bubble Sort):通过不断比较相邻元素的大小,将较大的元素逐步“冒泡”到数组的末尾。
2. 选择排序(Selection Sort):每次从未排序的数组中选择最小(或最大)的元素,放到已排序数组的末尾。
3. 插入排序(Insertion Sort):将数组分为已排序和未排序两个部分,每次将未排序部分中的元素插入到已排序部分的正确位置。
4. 快速排序(Quick Sort):选择一个基准元素,将数组分成两部分,将小于基准的元素放在左边,大于基准的元素放在右边,然后递归地对两部分进行排序。
5. 归并排序(Merge Sort):将待排序数组递归地分成两部分,分别进行排序,然后再将两个有序的数组合并成一个有序的数组。
6. 二分查找(Binary Search):对于有序数组,通过比较中间元素和目标值的大小,缩小查找范围,直到找到目标值或查找范围为空。
7. 线性查找(Linear Search):对于无序数组,逐个比较数组中的元素和目标值,直到找到目标值或遍历完整个数组。
8. 求阶乘(Factorial):使用递归方式或循环方式计算给定数字的阶乘。
9. 斐波那契数列(Fibonacci Sequence):使用递归方式或循环方式生成斐波那契数列。
10. 汉诺塔(Tower of Hanoi):使用递归方式实现汉诺塔问题的解决,将一组盘子从一个柱子移动到另一个柱子。
11. 判断回文数(Palindrome):判断给定数字是否为回文数,即正序和倒序相同。
12.求最大公约数(GCD):使用辗转相除法或欧几里德算法求两个数的最大公约数。
13.求最小公倍数(LCM):通过最大公约数求得最小公倍数。
14. 求质数(Prime Number):判断给定数是否为质数,即只能被1和自身整除。
c语言基础算法知识
c语言基础算法知识C语言基础算法知识概述:C语言作为一种广泛应用的编程语言,其基础算法知识对于程序员来说至关重要。
本文将从常见的算法知识入手,介绍C语言中常用的算法及其应用。
一、排序算法排序算法是计算机科学中最基础也是最常用的算法之一。
常见的排序算法有冒泡排序、选择排序、插入排序、快速排序、归并排序等。
这些算法的实现原理各不相同,但都能对一组数据进行排序。
1. 冒泡排序冒泡排序是一种简单直观的排序算法,它重复地遍历待排序的元素,比较相邻的两个元素并将它们交换顺序,直至整个序列有序。
2. 选择排序选择排序是一种简单直观的排序算法,它每次从待排序的数据中选择最小(或最大)的元素,将其放到已排序序列的末尾。
3. 插入排序插入排序是一种简单直观的排序算法,它将待排序的数据分为已排序和未排序两部分,每次从未排序中取出一个元素插入到已排序的合适位置,直至整个序列有序。
4. 快速排序快速排序是一种高效的排序算法,它通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有元素都比另一部分的元素小,然后对这两部分继续进行排序,直至整个序列有序。
5. 归并排序归并排序是一种稳定的排序算法,它采用分治策略,将待排序的数据不断二分,然后对子序列进行排序,最后将排序好的子序列合并成一个有序序列。
二、查找算法查找算法是在一组数据中寻找指定元素的算法。
常见的查找算法有线性查找、二分查找、哈希查找等。
1. 线性查找线性查找是一种简单直观的查找算法,它从待查找的数据中依次比较每个元素,直到找到目标元素或遍历完整个序列。
2. 二分查找二分查找是一种高效的查找算法,它要求待查找的数据必须是有序的,通过每次将查找范围缩小一半,直到找到目标元素或查找范围为空。
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语⾔实现汉诺塔游戏操作就是:A B 号码A的塔顶⼀层放在号码B的塔顶。
如1(空格) 3 回车。
话说有⼈能把我这C的代码添加到QT界⾯框架上去么?代码写的不好,维护性不够,只能玩8层的,写完以后发现很难拓展,软件⼯程,设计模式有待提⾼....⾥⾯提⽰输⼊等级的装B⽤了,没有实现,⼤家随便输⼊个个位数就可以玩了。
stackfunc.c#include"STACK.h"#include<stdio.h>extern ceng CENG[SIZE];//数据⼊栈void push_stack(stack*p,int number){p->arr[p->head]=number;p->head++;}//初始化栈1void init_stack1(stack*p){p->head=0;push_stack(p,1);push_stack(p,2);push_stack(p,3);push_stack(p,4);push_stack(p,5);push_stack(p,6);push_stack(p,7);push_stack(p,8);}//初始化栈2 3void init_stack2_3(stack* p1,stack* p2){p1->head=0;p1->arr[p1->head]=0;p2->head=0;p2->arr[p2->head]=0;}//弹出栈顶元素int pop_stack(stack* p){p->head--;return p->arr[p->head];}//访问栈顶元素int top_stack(stack* p){return p->arr[p->head-1];}//⽐较两个栈顶元素的⼤⼩int sizecmp_stack(stack* p1,stack* p2){if(p1->arr[p1->head-1]>p2->arr[p2->head-1])return 1;else if(p1->arr[p1->head-1]<p2->arr[p2->head-1])return -1;else return 0;}//测出栈的⾼度int high_stack(stack* p){return p->head;}//是否为空栈int empty_stack(stack* p){return p->head==0;}//是否栈满int full_stack(stack* p){return p->head==SIZE;}//初始化层1void init_ceng1(ceng* p){p->number=1;p->row=SIZE-1;p->col=0;}//初始化层2void init_ceng2(ceng* p){p->number=2;p->row=SIZE-2;p->col=0;}//初始化层3void init_ceng3(ceng* p){p->number=3;p->row=SIZE-3;p->col=0;}//初始化层4void init_ceng4(ceng* p){p->number=4;p->row=SIZE-4;p->col=0;}//初始化层5void init_ceng5(ceng*p){p->number=5;p->row=SIZE-5;p->col=0;}//初始化层6void init_ceng6(ceng*p){p->number=6;p->row=SIZE-6;p->col=0;}//初始化层7void init_ceng7(ceng*p){p->number=7;p->row=SIZE-7;p->col=0;}//初始化层8void init_ceng8(ceng*p){p->number=8;p->row=SIZE-8;p->col=0;}//移动层void move_ceng(int level,int *nrow,int *ncol,stack*p1,stack* p2,stack* p3,int stdec){stack* arr[3];arr[0]=p1;arr[1]=p2;arr[2]=p3;*nrow=level-1-high_stack(arr[stdec]);*ncol=stdec;}//显⽰图⽚void show_map(void){int i,j;for(i=0;i<SIZE;i++){for(j=0;j<3;j++){if(CENG[0].row==i&&CENG[0].col==j){printf(" | 1 | ");}else if(CENG[1].row==i&&CENG[1].col==j){printf(" | 2 | ");}else if(CENG[2].row==i&&CENG[2].col==j){printf(" | 3 | ");}else if(CENG[3].row==i&&CENG[3].col==j){printf(" | 4 | ");}else if(CENG[4].row==i&&CENG[4].col==j){printf(" | 5 | ");}else if(CENG[5].row==i&&CENG[5].col==j){printf(" | 6 | ");}else if(CENG[6].row==i&&CENG[6].col==j){printf(" | 7 | ");}else if(CENG[7].row==i&&CENG[7].col==j){printf(" |8| ");}else printf(" ");}printf("\n");}printf("=====================================================================\n"); }main.c#include"STACK.h"#include<stdio.h>ceng CENG[SIZE];int main(){int res=1,dec=1;char con;int newrow;int newcol;int step=0;int level=0;while(1){ if (level==0){do{printf("请输⼊游戏等级:\n");scanf("%d",&level);if(level<=0||level>8)printf("等级范围错误,重新输⼊\n");}while(level<=0||level>8);}level=8;newrow=0,newcol=0;stack STACK[3];//初始化3个栈init_stack1(&STACK[0]);init_stack2_3(&STACK[1],&STACK[2]);//初始化8个层init_ceng1(&CENG[0]);init_ceng2(&CENG[1]);init_ceng3(&CENG[2]);init_ceng4(&CENG[3]);init_ceng5(&CENG[4]);init_ceng6(&CENG[5]);init_ceng7(&CENG[6]);init_ceng8(&CENG[7]);while(1){//打印画⾯switch(level){case 1:show_map();break;case 2:show_map();break;case 3:show_map();break;case 4:show_map();break;case 5:show_map();break;case 6:show_map();break;case 7:show_map();break;case 8:show_map();break;}while(1){// printf("游戏等级为:%d\n",level);// printf("源栈最⾼层是%d ......\n",top_stack(&STACK[res]));printf(" ⼀号的⾼度%d ",STACK[0].head);printf(" ⼆号的⾼度%d ",STACK[1].head);printf(" 三号的⾼度%d\n",STACK[2].head);printf("\n已经⾛的步数为 %d \n",step);//选择源⽬标scanf("%d",&res);scanf("%d",&dec);res--;dec-- ;if(!(res>=0&&res<3&&dec>=0&&dec<3))/*||(empty_stack(&STACK[res]))*/{ printf("\n\n输⼊范围超出\n");}else if(empty_stack(&STACK[res])==1){printf("%d\n",STACK[0].head);printf("\n\n源栈空\n");}else if(sizecmp_stack(&STACK[res],&STACK[dec])<0){ printf("\n\n⼤块的不能放在⼩块的上⾯\n");}else{if(dec!=res){printf("\n\n\n正在移动层块....\n");step++;move_ceng(level,&newrow,&newcol,&STACK[0],&STACK[1],&STACK[2],dec); CENG[top_stack(&STACK[res])-1].row=newrow;CENG[top_stack(&STACK[res])-1].col=newcol;push_stack(&STACK[dec],pop_stack(&STACK[res]));break;}else{printf("\n\n\n放轻松\n");}break;}show_map();}if (full_stack(STACK+1)==1||full_stack(STACK+2)==1){printf("完成了汉诺塔!\n");level++;break;}}show_map();printf("是否继续游戏?继续请输⼊y,否则按其它键\n");scanf("%*[^\n]");scanf("%*c");scanf("%c",&con);if(con!='y')break;}return 0;}STACK.h#ifndef __STACK_H__#define __STACK_H__#define SIZE 8typedef struct STACK{int head;int arr[SIZE];}stack;typedef struct CENG{int number;int row;int col;}ceng;extern ceng CENG[SIZE];//⼊栈void push_stack(stack*,int);//初始化栈1void init_stack1(stack*);//初始化栈2和3void init_stack2_3(stack*,stack*);//出栈int pop_stack(stack*);//访问栈顶元素int top_stack(stack*);//⽐较栈顶元素⼤⼩ -1 1int sizecmp_stack(stack*,stack*);//判断栈的⾼度int high_stack(stack*);//判断栈是否为空1 0int empty_stack(stack*);//判断栈是否满1 0int full_stack(stack*);//初始化层1void init_ceng1(ceng*);//初始化层2void init_ceng2(ceng*);//初始化层3void init_ceng3(ceng*);//初始化层4void init_ceng4(ceng*);//初始化层5void init_ceng5(ceng*);//初始化层6void init_ceng6(ceng*);//初始化层7void init_ceng7(ceng*);//初始化层8void init_ceng8(ceng*);//移动层块void move_ceng(int ,int * a,int *b,stack*,stack*,stack*,int k );//打印画⾯void show_map();#endif演⽰图⽚以上所述就是本⽂的全部内容了,希望能够对⼤家学习C语⾔的递归算法有所帮助。
c++汉诺塔问题递归算法
c++汉诺塔问题递归算法汉诺塔问题是经典的递归问题,它可以帮助我们理解和掌握递归算法的思想。
在C++中,我们可以通过递归来解决汉诺塔问题。
汉诺塔问题的描述如下:有三根柱子A、B、C,A柱子上有n 个盘子,盘子的大小不一,大的在下,小的在上。
现在要将A 柱子上的盘子移动到C柱子上,并且每次只能移动一个盘子,并且大的盘子不能放在小的盘子上面。
要求通过借助柱子B来实现移动。
下面我们先给出解决汉诺塔问题的递归代码:```cpp#include <iostream>void hanoi(int n, char A, char B, char C) {if (n == 1) {std::cout << "Move disk 1 from " << A << " to " << C << std::endl;return;}hanoi(n - 1, A, C, B);std::cout << "Move disk " << n << " from " << A << " to " << C << std::endl;hanoi(n - 1, B, A, C);}int main() {int n = 3; // 盘子的个数hanoi(n, 'A', 'B', 'C');return 0;}```上面的代码使用了递归的思想来解决汉诺塔问题。
函数`hanoi()`接受四个参数,n表示盘子的个数,A、B、C表示三根柱子的名称。
当n等于1时,表示只有一个盘子需要移动,直接将它从A柱子移动到C柱子即可。
当n大于1时,我们可以把问题简化为两个步骤:将n-1个盘子从A柱子通过借助C柱子移动到B柱子,然后将最后一个盘子从A柱子移动到C柱子,最后将n-1个盘子从B柱子通过借助A柱子移动到C 柱子。
C语言递归调用实例——汉诺塔问题动画实现(附完整代码)
二、程序框架
古人云,不谋全局者,不足谋一域。同样,在编写代码之前,我们必 须得有个大体的思路和整体上的把握。不能一上来就稀里糊涂地乱敲一通。 当然,这里我也只能仅仅谈自己的个人想法,不一定就是最优的解决方案, 还希望能和大家一起相互交流,共同进步。整个程序的框架,我把它分为 动画效果和核心算法两大部分。我首先实现的是动画效果部分,等能够实 现盘子的随意移动后,我才开始研究核心算法的实现。这样一来,在核心 算法部分,我们正好可以利用前面的动画效果来直观地反映出我们的思路, 有助于代码的调试和缩短程序的开发周期。为了尽量减少废话,我们可以 用一张图来进行表示:
图 1-1 移动第一个圆盘..................................................................................................................... 4 图 1-2 移动第二个圆盘...................................................................................................................... 5 图 1-3 移动最后一个圆盘................................................................................................................. 6
能移动一个圆盘,且圆盘在放到棒上时,大的不能放在小的上面。中间的一根
棒作为辅助移动用。” 事实上,对此曾经有人作过分析,按这个规则,众僧耗尽毕生精力也
不可能完成圆盘的移动,因为需要移动圆盘的次数是一个天文数字 18446744073709551615(64 个圆盘需要移动的次数为 2 的 64 次方)。假设 1us 进行一次移动,也需要约一百万年的时间,使用计算机也很难解决 64
汉诺塔
汉诺塔一、需求分析:1、输入时每次只需输入一个n值,无范围限制。
2、输出的形式,输出移动盘子的所有步骤,每一句为一个步骤。
3、功能,实现汉诺塔的移动步骤。
4、测试数据,n=-1,0,1,3,4。
二、概要设计:各函数的调用关系:三、详细设计:见源码:hannuota.cpp文件的实现#include<iostream>using namespace std;int num; //全局变量void move(char a,char c) //移动函数{cout<<"第"<<++num<<"步:"<<a<<"柱子上的盘子移动到"<<c<<"柱子上."<<endl;}void hanuota(int num,char a,char b,char c) //递归调用函数{if(num<1){cout<<"无可移动盘子."<<endl;return ;}if(num==1){move(a,c);}else{hanuota(num-1,a,c,b);move(a,c);hanuota(num-1,b,a,c);}}int main() //main函数{int i;while(cin>>i){num=0;hanuota(i,'A','B','C');}return 0;}四、调式分析:1、调式时递归函数不正确,因为参数顺序不正确,经改正后最终得到了正确的结果。
2、体会,学会了递归函数的使用。
五、用户使用说明:每次只需输入一个n值表示盘子数,即可得到结果。
六、测试结果:。
Hanoi(汉诺)塔问题
11:59
35
• 把上面3个步骤分成两类操作:
(1) 将n-1个盘从一个座移到另一个座上(n> 1)。这就是大和尚让小和尚做的工作,它 是一个递归的过程,即和尚将任务层层下放, 直到第64个和尚为止。 (2) 将1个盘子从一个座上移到另一座上。这是 大和尚自己做的工作。
11:59
36
• 编写程序。
11:59
1
A
B
C
11:59
2
• 解题思路:
– 要把64个盘子从A座移动到C座,需要移动大 约264 次盘子。一般人是不可能直接确定移动 盘子的每一个具体步骤的 – 老和尚会这样想:假如有另外一个和尚能有办 法将上面63个盘子从一个座移到另一座。那么, 问题就解决了。此时老和尚只需这样做:
11:59
11:59
37
#include <stdio.h> int main() { void hanoi(int n,char one, char two,char three); int m; printf(“the number of diskes:"); scanf("%d",&m); printf("move %d diskes:\n",m); hanoi(m,'A','B','C'); }
A
B
C
11:59
31
将2个盘子从B移到C的过程
A
B
C
11:59
32
将2个盘子从B移到C的过程
A
B
C
11:59
33
• 由上面的分析可知:将n个盘子从A座移到 C座可以分解为以下3个步骤:
c语言十大算法案例
c语言十大算法案例C语言是一种广泛应用于编程的高级语言,具有简单、灵活、高效等特点。
在C语言中,有许多经典的算法案例,这些算法案例不仅有助于提高编程能力,还能帮助我们理解计算机科学的基本原理。
下面列举了十个C语言的经典算法案例。
1. 冒泡排序算法:冒泡排序是一种简单但效率较低的排序算法,它通过多次比较和交换相邻元素的方式将最大或最小的元素逐步移动到数组的一端。
2. 快速排序算法:快速排序是一种常用的排序算法,它通过选择一个基准元素,将数组分成两个子数组,然后对子数组进行递归排序。
3. 二分查找算法:二分查找是一种高效的查找算法,它通过将查找范围缩小一半来快速定位目标元素。
4. 链表反转算法:链表反转是一种常见的操作,它可以将链表中的节点顺序逆转。
5. 汉诺塔算法:汉诺塔是一种经典的递归问题,它通过将圆盘从一个柱子移动到另一个柱子来演示递归的思想。
6. 最大公约数算法:最大公约数是指能够同时被两个或多个整数整除的最大正整数,求最大公约数的算法有多种,如辗转相除法和欧几里德算法。
7. 斐波那契数列算法:斐波那契数列是一个数列,其中每个数字都是前两个数字之和,求斐波那契数列的算法有多种,如递归和循环。
8. 图的深度优先搜索算法:深度优先搜索是一种用于遍历图的算法,它通过递归的方式依次访问图中的每个节点。
9. 图的广度优先搜索算法:广度优先搜索也是一种用于遍历图的算法,它通过队列的方式依次访问图中的每个节点。
10. 最短路径算法:最短路径算法用于找到图中两个节点之间的最短路径,常用的最短路径算法有迪杰斯特拉算法和弗洛伊德算法。
这些算法案例涵盖了排序、查找、链表操作、递归、图算法等多个方面,是C语言学习中不可或缺的部分。
通过学习和理解这些经典算法案例,我们可以提高自己的编程能力,并在解决实际问题时能够选择合适的算法。
希望本文能够对读者有所帮助,激发他们对C 语言算法的兴趣,并在编程的道路上不断进步。
c++汉诺塔问题递归算法
c++汉诺塔问题递归算法汉诺塔问题是一个经典的数学问题,也是计算机科学中常用的递归问题。
该问题的描述是:有三个柱子(A、B、C),A柱子上放着从小到大依次排列的n个圆盘,目标是将这些圆盘从A柱子移动到C柱子,每次只能移动一个圆盘,并且在移动过程中,大的圆盘不能放在小的圆盘上。
要解决这个问题,可以使用递归算法来实现。
递归是一种解决问题的方法,通过将问题简化为规模更小的子问题来解决。
对于汉诺塔问题,我们可以将其简化为将n-1个圆盘从A柱子移动到B柱子,然后将最大的圆盘从A柱子移动到C柱子,最后再将n-1个圆盘从B柱子移动到C柱子。
下面是一个使用C++编写的递归算法解决汉诺塔问题的示例代码:```cpp#include<iostream>using namespace std;void hanoi(int n, char a, char b, char c) {if (n == 1) {cout << "Move disk 1 from " << a << " to " << c << endl;return;}hanoi(n - 1, a, c, b);cout << "Move disk " << n << " from " << a << " to " << c << endl;hanoi(n - 1, b, a, c);}int main() {int n;cout << "Enter the number of disks: ";cin >> n;cout << "The moves are:" << endl;hanoi(n, 'A', 'B', 'C');return 0;}```在这段代码中,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<。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
一位法国数学家曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。
印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。
不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。
僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
不管这个传说的可信度有多大,如果考虑一下把64片金片,由一根针上移到另一根针上,并且始终保持上小下大的顺序。
这需要多少次移动呢?这里需要递归的方法。
假设有n片,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且
f(k+1)=2*f(k)+1。
此后不难证明f(n)=2^n-1。
n=64时,
f(64)= 2^64-1=18446744073709551615
假如每秒钟一次,共需多长时间呢?一个平年365天有 31536000 秒,闰年366天有31622400秒,平均每年31556952秒,计算一下,
18446744073709551615/31556952=584554049253.855年
这表明移完这些金片需要5845亿年以上,而地球存在至今不过45亿年,太阳系的预期寿命据说也就是数百亿年。
真的过了5845亿年,不说太阳系和银河系,至少地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭。
算法介绍
其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n –1(有兴趣的可以自己证明试试看)。
后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。
首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C;
若n为奇数,按顺时针方向依次摆放 A C B。
(1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。
(2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。
即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。
这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。
(3)反复进行(1)(2)操作,最后就能按规定完成汉诺塔的移动。
所以结果非常简单,就是按照移动规则向一个方向移动金片:
如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C
#include<stdio.h>
void main()
{void f(int n,char x,char y,char z); int m;
scanf("%d",&m);
f(m,'a','b','c');
}
void f(int n,char x,char y,char z ) {if(n==1)
printf("%c>>%c\n",x,z);
else if(n>1)
{f(n-1,x,z,y);
printf("%c>>%c\n",x,z);
f(n-1,y,x,z);}
}
N=3
N=4。