Hanoi学习笔记
来源:互联网 发布:在线ftp源码 编辑:程序博客网 时间:2024/04/28 06:58
汉诺塔学习,今天终于搞懂了汉诺塔的实现过程,说起来很麻烦,但是实现真的递归一下就是很简单的事了。
在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石
针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所
谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针
上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就
将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。假设有n片,移动次数是f(n).显然f(1)=1,f(2)=
3,f(3)=7,且f(k+1)=2*f(k)+1 (f(k+1)可以理解为现将k个金片全部移动到第三个针上面,然后再将最后的第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-1个盘子移动到柱子C上,然后把最大的一块放在B上,最后把C上的所有盘子移动到B上,
由此我们得出表达式:
H(1) = 1
H(n) = 2*H(n-1)+1 (n>1)
public static void move(int number,int fromtower,int totower,int auxtower){
if(number==1)
System.out.println("Move disk 1 from the "+fromtower+" to the "+totower);
else{
move(number-1,fromtower,auxtower,totower);
System.out.println("Move disk "+number+" from the "+fromtower+" to the "+totower);
move(number-1, auxtower, totower, fromtower);
}
move(int num, int fromtower, int totower, int auxtower),是进行move的函数,可以这样理解为将num个盘子
auxtower,从fromtower移动到totower,然后拆分问题,进行到将n-1个盘子从fromtower移动到totower,经过auxtower
的辅助,然后将最后一个盘子移到totower上面,最后再将auxtower上面的盘子全部移动到totower上面借助于fromtower。
在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石
针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所
谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针
上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就
将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。假设有n片,移动次数是f(n).显然f(1)=1,f(2)=
3,f(3)=7,且f(k+1)=2*f(k)+1 (f(k+1)可以理解为现将k个金片全部移动到第三个针上面,然后再将最后的第k+1
个金块放到第二个针上面,然后再次利用三根针将三针上面的金片移动到二针上面),有递归表达式可以求得f(n)
=2^n-1
n=64时,
f(64)= 2^64-1=18446744073709551615
假如每秒钟一次
#include <stdio.h>void move(int n, int fromtower, int midtower, int totower){ if (n == 1) { printf("step %d: move disk 1 from tower %d to tower %d.\n", count++, fromtower, totower); } else { move(n-1, fromtower, midtower, totower); printf("step %d: move disk %d from tower %d to tower %d.\n", count++, n, fromtower, totower); move(n-1, midtower, totower, fromtower); }}int main(){ int n; printf("Please input the number of disks:\n"); scanf("%d", &n); move(n, 1, 3, 2); return 0;}
,共需多长时间呢?一个平年365天有 31536000 秒,闰年366天有31622400秒,平均每年31556952秒,计算一下,
18446744073709551615/31556952=584554049253.855年
这表明移完这些金片需要5845亿年以上,而地球存在至今不过45亿年,太阳系的预期寿命据说也就是数百亿年。
真的过了5845亿年,不说太阳系和银河系,至少地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭.
先我们肯定是把上面n-1个盘子移动到柱子C上,然后把最大的一块放在B上,最后把C上的所有盘子移动到B上,
由此我们得出表达式:
H(1) = 1
H(n) = 2*H(n-1)+1 (n>1)
public static void move(int number,int fromtower,int totower,int auxtower){
if(number==1)
System.out.println("Move disk 1 from the "+fromtower+" to the "+totower);
else{
move(number-1,fromtower,auxtower,totower);
System.out.println("Move disk "+number+" from the "+fromtower+" to the "+totower);
move(number-1, auxtower, totower, fromtower);
}
move(int num, int fromtower, int totower, int auxtower),是进行move的函数,可以这样理解为将num个盘子
auxtower,从fromtower移动到totower,然后拆分问题,进行到将n-1个盘子从fromtower移动到totower,经过auxtower
的辅助,然后将最后一个盘子移到totower上面,最后再将auxtower上面的盘子全部移动到totower上面借助于fromtower。
- Hanoi学习笔记
- 《数据结构(严蔚敏版)》学习笔记(四)——Hanoi塔问题
- Hanoi
- Hanoi
- Hanoi
- Hanoi。。。。
- Hanoi
- hanoi
- Hanoi
- hanoi
- hanoi
- hanoi
- hanoi
- hanoi
- hanoi
- Hanoi
- hanoi
- Hanoi
- Android - Unparsed aapt error(s)错误的处理方法
- Source Insight将gcc的输出结果链接到文件+行
- Android UI学习 - FrameLayou和布局优化
- JAVA 中进行网络通信时 两端 序列化对象的类所处的包名必须一致
- Android UI学习 - TableLayout
- Hanoi学习笔记
- 数据结构笔记---单链表
- Android UI学习 - Tab的学习和使用
- Android UI学习 - GridView和ImageView的使用
- GDTR和LDTR如何把虚拟地址转换成线性地址
- 用c++和python写GUI程序(python嵌入方式)
- Activity生命周期的学习以及Logcat的使用
- Activity的跳转与传值
- 单链表的反转