汉诺塔问题思路的证明
前言
问题描述:在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
问题分析
其实答案的思路很简单:
- 设A上有n个圆盘
- 如果n=1,就直接将 A->C ,Move( A, C);
- 如果是其他情况
- 先将前 A 上的 n-1 个圆盘移动到 B 上,Hanoi(n - 1, A, C, B)
- 再将 A 上的最后一个圆盘移动到 C上,Move(A, C)
- 最后将 B 上的 n-1 个圆盘移动的 C 上,Hanoi(n - 1, B, A, C)
但为什么这样可行?这个比较让人费解。这里我给大家提供一个思路:利用数学归纳法。
证:
假设 f(n) 操作代表把 n 个圆盘从 A 杆移动到 C 杆
注意,将 n 个圆盘无论是进行 A->C、B->C、A->B、C->B,B->A、C->A,这几个操作是完全等价的
首先,f(1) 操作一定可行
现假设 f(n) 操作可行,则 f(n+1) 操作代表要把 n+1 个圆盘从 A 杆移动到 C 杆。
因为 f(n) 操作可行,所以可以把 n 个圆盘从 A 杆移动到 B 杆,将 A 杆剩余的最后一个圆盘直接放到 C 杆。
然后还是因为 f(n) 可行,所以可以直接把 B 杆的 n 个圆盘移动到 C 杆
由此可知 f(n+1) 的操作可行。
得证:当 n∈{1,2,3,…} 时, f(n) 操作可行
下面是C语言版完整的案例,P121_6 代表题号,这个代码是我刷题的时候写的。起始真正的操作只有 P121_6 这一个函数,其他函数都是用于输出相关信息的,方便我们观察究竟发生了什么。
typedef struct {int *A;int *B;int *C;int top[3];
}s_Hannoi,*p_hannoi;// 汉诺塔堆栈初始化
void P121_6_init(s_Hannoi& h, int n)
{int i = n-1;h.A = (int*)malloc(sizeof(int) * n);h.B = (int*)malloc(sizeof(int) * n);h.C = (int*)malloc(sizeof(int) * n);h.top[0] = i;h.top[1] = -1;h.top[2] = -1;for (;i >= 0;i--) {h.A[i] = i;}
}void P121_6_Move(s_Hannoi& h,char out,char in)
{int temp = -1,i,j;printf("%c->%c:\n", out, in);switch (out) {case 'A': temp = h.A[h.top[0]];--h.top[0];break;case 'B':temp = h.B[h.top[1]];--h.top[1];break;case 'C':temp = h.C[h.top[2]];--h.top[2];break;}switch (in) {case 'A':++h.top[0];h.A[h.top[0]] = temp;break;case 'B':++h.top[1];h.B[h.top[1]] = temp;;break;case 'C':++h.top[2];h.C[h.top[2]] = temp;break;}// 打印当前结构printf("\tA:");for (i = 0;i < h.top[0]+1;i++) {printf("%d,", h.A[i]);}printf("\n\tB:");for (i = 0;i < h.top[1]+1;i++) {printf("%d,", h.B[i]);}printf("\n\tC:");for (i = 0;i < h.top[2]+1;i++) {printf("%d,", h.C[i]);}printf("\n");
}// 汉诺塔问题
void P121_6(s_Hannoi& h,int n,char A,char B,char C)
{if (n == 1) {P121_6_Move(h, A, C);}else {P121_6(h, n - 1, A, C, B);P121_6_Move(h, A, C);P121_6(h, n - 1, B, A, C);}
}int main()
{printf("***********************\n");s_Hannoi h;P121_6_init(h, 6);P121_6(h, 6, 'A', 'B', 'C');
}
汉诺塔问题思路的证明相关推荐
- c语言 统计数量用count_C语言编程学习之递归实现汉诺塔图解!还有零基础入门视频~...
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
- 汉诺塔(hanio)
1.汉诺塔的背景: 法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地 ...
- 汉诺塔问题的Java实现(递归与非递归)
文章目录 一.汉诺塔问题描述 二.汉诺塔解题思路 三.递归 四.非递归 一.汉诺塔问题描述 汉诺塔问题就是有三张柱子A.B.C,然后初始化在A上放了N个圆盘,圆盘按照小压大的方式堆放,需要用最少的步骤 ...
- 汉诺塔问题的递归求解
汉诺塔问题的递归求解 汉诺塔 解题思路 具体实现 汉诺塔 汉诺塔 汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱 ...
- java汉诺塔(含汉诺塔问题的详解)
目录 一:汉诺塔问题 二:汉诺塔问题思路 三:图示化思路 四:代码展示 一:汉诺塔问题 汉诺塔问题是一个经典的问题.汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说.大梵天创造世界的 ...
- c语言 汉诺塔游戏下载,使用C语言解决益智游戏——“汉诺塔”
说明: 文章所有内容截选自实验楼教程[3个C语言实例带你掌握递归方法论],教程里还有两个实例,感兴趣的可以点击查看: 文章主要是带你通过解决这个游戏来利用递归解决实际问题并掌握其核心思想,懂得如何使用 ...
- 计算组合数 汉诺塔 喵帕斯之天才算数少女 神奇的函数
计算组合数 Time Limit: 1000 ms Memory Limit: 32768 KiB Submit Statistic Problem Description 计算组合数.C(n,m), ...
- 经典汉诺塔问题的推理思路以及求解
汉诺塔是递归中的一道经典题目,接着我们看如何求解以及求解的思路. 首先了解汉诺塔 汉诺塔是给定三根柱子,通过一次移动一片圆盘将一根柱上所有圆盘移到另外一根柱上 而当圆盘数>=2时我们就要借助另外 ...
- 多图详解汉诺塔递归实现思路--含实现代码
前言 为了节约大家的时间,本文对汉诺塔的定义就不做赘述了,如果有小伙伴不清楚汉诺塔的规则可以直接点蓝字跳转过去. 本篇博客内容 汉诺塔实现的思路 用递归的方式实现汉诺塔 汉诺塔实现的思路 我们先以两个 ...
最新文章
- linux 用户态与内核态通信方式简介
- Flume的Collector
- All Things OpenTSDB
- thinkphp mysql 中文 问号_thinkphp分页中文参数乱码解决
- vue传递数组对象_详解vue组件三大核心概念
- 那些查了无数遍的问题
- html加载富文本_富文本图片懒加载解决方案
- matlab中删除照片_照片也有隐私,教你如何批量删除数码照片中的相机、光圈和地理位置等 EXIF 信息...
- tomcat源码阅读
- vyos as a firewall
- 树莓派4B监控CPU占用率、内存使用率、磁盘使用量以及CPU温度
- c++中 append()函数用法
- jpg转换成pdf转换器免费版
- 0813Python总结-tcp,udp及黏包,struck模块
- 【Linux】yum(Yellow dog Updater Modified)使用简介
- vue3获取url后面参数
- 2018年的总结和2019年的期望
- 从电路交换到分组交换——TDM、ATM
- 如何安装imgaug
- poi word设置字体背景颜色(也叫底纹)