一.起源:
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
二.抽象为数学问题:
如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数
~~~
解:
(1)n == 1
第1次 1号盘 A---->C sum = 1 次
(2) n == 2
第1次 1号盘 A---->B
第2次 2号盘 A---->C
第3次 1号盘 B---->C sum = 3 次
(3)n == 3
第1次 1号盘 A---->C
第2次 2号盘 A---->B
第3次 1号盘 C---->B
第4次 3号盘 A---->C
第5次 1号盘 B---->A
第6次 2号盘 B---->C
第7次 1号盘 A---->C sum = 7 次
不难发现规律:1个圆盘的次数 2的1次方减1
2个圆盘的次数 2的2次方减1
3个圆盘的次数 2的3次方减1
。 。 。 。 。
n个圆盘的次数 2的n次方减1
故:移动次数为:2^n - 1
~~~
三.调用方法的栈机制:(特点:先进后出)
从主线程开始调用方法(函数)进行不停的压栈和出栈操作,函数的调用就是将函数压如栈中,函数的结束就是函数出栈的过程,这样就保证了方法调用的顺序流,即当函数出现多层嵌套时,需要从外到内一层层把函数压入栈中,最后栈顶的函数先执行结束(最内层的函数先执行结束)后出栈,再倒数第二层的函数执行结束出栈,到最后,第一个进栈的函数调用结束后从栈中弹出回到主线程,并且结束。
四.算法分析(递归算法):
我们在利用计算机求汉诺塔问题时,必不可少的一步是对整个实现求解进行算法分析。到目前为止,求解汉诺塔问题最简单的算法还是同过递归来求,至于是什么是递归,递归实现的机制是什么,我们说的简单点就是自己是一个方法或者说是函数,但是在自己这个函数里有调用自己这个函数的语句,而这个调用怎么才能调用结束呢?,这里还必须有一个结束点,或者具体的说是在调用到某一次后函数能返回一个确定的值,接着倒数第二个就能返回一个确定的值,一直到第一次调用的这个函数能返回一个确定的值。
实现这个算法可以简单分为三个步骤:
(1) 把n-1个盘子由A 移到 B;
(2) 把第n个盘子由 A移到 C;
(3) 把n-1个盘子由B 移到 C;
从这里入手,在加上上面数学问题解法的分析,我们不难发现,移到的步数必定为奇数步:
(1)中间的一步是把最大的一个盘子由A移到C上去;
(2)中间一步之上可以看成把A上n-1个盘子通过借助辅助塔(C塔)移到了B上,
(3)中间一步之下可以看成把B上n-1个盘子通过借助辅助塔(A塔)移到了C上;
~~~
package com.imooc;
import java.util.Scanner;
public class TowerOfHanoi {
static int m =0; //标记移动次数
//实现移动的函数
public static void move(int disks,char N,char M)
{
System.out.println("第" + (++m) +" 次移动 : " +" 把 "+ disks+" 号圆盘从 " + N +" ->移到-> " + M);
}
//递归实现汉诺塔的函数
public static void hanoi(int n,char A,char B,char C)
{
if(n == 1 ) //圆盘只有一个时,只需将其从A塔移到C塔
TowerOfHanoi.move(1, A, C); //将编b号为1的圆盘从A移到C
else
{
//否则
hanoi(n - 1, A, C, B); //递归,把A塔上编号1~n-1的圆盘移到B上,以C为辅助塔
TowerOfHanoi.move(n, A, C); //把A塔上编号为n的圆盘移到C上
hanoi(n - 1, B, A, C) ; //递归,把B塔上编号1~n-1的圆盘移到C上,以A为辅助塔
}
}
public static void main(String[] args) {
Scanner imput = new Scanner(System.in);
char A = 'A';
char B = 'B';
char C = 'C';
System.out.println("*************************************");
System.out.println("这是汉诺塔问题(把A塔上编号从小号到大号的圆盘从A塔通过B辅助塔移动到C塔上去");
System.out.println("***************************************");
System.out.print("请输入圆盘的个数:");
int disks = imput.nextInt();
TowerOfHanoi.hanoi(disks, A, B, C);
System.out.println(">>移动了" + m + "次,把A上的圆盘都移动到了C上");
imput.close();
}
}
**********************************************************************
这是汉诺塔问题(把A塔上编号从小号到大号的圆盘从A塔通过B辅助塔移动到C塔上去
**********************************************************************
请输入圆盘的个数:4
第1 次移动 : 把 1 号圆盘从 A ->移到-> B
第2 次移动 : 把 2 号圆盘从 A ->移到-> C
第3 次移动 : 把 1 号圆盘从 B ->移到-> C
第4 次移动 : 把 3 号圆盘从 A ->移到-> B
第5 次移动 : 把 1 号圆盘从 C ->移到-> A
第6 次移动 : 把 2 号圆盘从 C ->移到-> B
第7 次移动 : 把 1 号圆盘从 A ->移到-> B
第8 次移动 : 把 4 号圆盘从 A ->移到-> C
第9 次移动 : 把 1 号圆盘从 B ->移到-> C
第10 次移动 : 把 2 号圆盘从 B ->移到-> A
第11 次移动 : 把 1 号圆盘从 C ->移到-> A
第12 次移动 : 把 3 号圆盘从 B ->移到-> C
第13 次移动 : 把 1 号圆盘从 A ->移到-> B
第14 次移动 : 把 2 号圆盘从 A ->移到-> C
第15 次移动 : 把 1 号圆盘从 B ->移到-> C
>>移动了15次,把A上的圆盘都移动到了C上
~~~
- 说明
- 排序
- java实现
- 二分归并排序
- 快速排序
- js实现
- 冒泡排序 (Bubble Sort)
- 快速排序-js
- ES6-rest参数
- 比较排序
- 堆排序
- 插入排序
- 归并排序
- 选择排序
- shellSort
- 排序基础知识
- 其他
- Rabbit
- chickenProblem
- 汉诺塔
- 取出两个字符串中开头相同的部分
- 两个七进制输入,输出七进制
- 二维数组(矩阵)对角线输出
- 根据概率取值
- 最小编辑距离算法
- 列划分算法
- 数组去重
- 数组去重1
- 在一天里,钟表的时针和分针会重合多少次?
- 找第二大问题
- Raft算法
- B-tree
- Leetcode JAVA实现
- leetcode1. 2 Sum
- leetcode2. Add Two Numbers
- leetcode7. Reverse Integer
- leetcode8. String to Integer (atoi)
- leetcode12. Integer to Roman
- leetcode13. Roman to Integer
- leetcode15. 3Sum
- leetcode18. 4Sum
- leetcode20. Valid Parentheses
- leetcode26. Remove Duplicates from Sorted Array
- leetcode27. Remove Element
- leetcode58. Length of Last Word
- leetcode66. Plus One
- leetcode67. Add Binary
- leetcode80. Remove Duplicates from Sorted Array II
- leetcode 88. Merge Sorted Array
- leetcode101. Symmetric Tree
- leetcode104. Maximum Depth of Binary Tree
- leetcode110. Balanced Binary Tree
- leetcode118. Pascal's Triangle
- leetcode119. Pascal's Triangle II
- leetcode121. Best Time to Buy and Sell Stock
- leetcode125. Valid Palindrome
- leetcode136. Single Number
- leetcode144. Binary Tree Preorder Traversal
- leetcode145. Binary Tree Postorder Traversal
- leetcode155. Min Stack
- leetcode169. Majority Element
- leetcode171. Excel Sheet Column Number
- leetcode172. Factorial Trailing Zeroes
- leetcode189. Rotate Array
- leetcode191. Number of 1 Bits
- leetcode202. Happy Number
- leetcode203. Remove Linked List Elements
- leetcode204. Count Primes
- leetcode225. Implement Stack using Queues
- leetcode226. Invert Binary Tree
- leetcode231. Power of Two
- leetcode232. Implement Queue using Stacks
- leetcode234. Palindrome Linked List
- leetcode237. Delete Node in a Linked List
- leetcode242. Valid Anagram
- leetcode258. Add Digits
- leetcode263. Ugly Number
- leetcode283. Move Zeroes
- leetcode292. Nim Game
- leetcode344. Reverse String
- leetcode371. Sum of Two Integers
- leetcode804. Unique Morse Code Words
- Leetcode JS 实现
- Js-leetcode 1. Two Sum
- Js-leetcode 2. Add Two Numbers
- Js-leetcode 10. Regular Expression Matching
- Js-leetcode 14. Longest Common Prefix
- Js-leetcode 17.Letter Combinations of a Phone Number
- Js-leetcode 20. Valid Parentheses
- Js-leetcode 27. Remove Element
- Js-leetcode 30. Substring with Concatenation of All Words
- Js-leetcode 35. Search Insert Position
- Js-leetcode 41. First Missing Positive
- Js-leetcode 48. Rotate Image
- Js-leetcode 53. Maximum Subarray
- Js-leetcode 54. Spiral Matrix
- Js-leetcode 73. Set Matrix Zeroes
- Js-leetcode 75. Sort Colors
- Js-leetcode 85. Maximal Rectangle
- Js-leetcode 89. Gray Code
- Js-leetcode 93.Restore IP Addresses
- Js-leetcode 98. Validate Binary Search Tree
- Js-leetcode 104. Maximum Depth of Binary Tree
- Js-leetcode 118. Pascal's Triangle
- Js-leetcode 121. Best Time to Buy and Sell Stock
- Js-leetcode 136. Single Number
- Js-leetcode 164. Maximum Gap
- Js-leetcode 189. Rotate Array
- Js-leetcode 215. Kth Largest Element in an Array
- Js-leetcode 217. Contains Duplicate
- Js-leetcode 258. Add Digits
- Js-leetcode 263.Ugly Number
- Js-leetcode 283. Move Zeroes
- Js-leetcode 326. Power of Three
- Js-leetcode 434. Number of Segments in a String
- Js-leetcode 459. Repeated Substring Pattern
- Js-leetcode 507. Perfect Number
- Js-leetcode 537. Complex Number Multiplication
- Js-leetcode 541. Reverse String II
- Js-leetcode 551. Student Attendance Record I
- Js-leetcode 557. Reverse Words in a String III
- Js-leetcode 605. Can Place Flowers
- Js-leetcode 606. Construct String from Binary Tree
- Js-leetcode 621. Task Scheduler
- Js-leetcode 622. Design Circular Queue
- Js-leetcode 633. Sum of Square Numbers
- Js-leetcode 657. Robot Return to Origin
- Js-leetcode 682. Baseball Game
- Js-leetcode 686. Repeated String Match
- Js-leetcode 696. Count Binary Substrings
- Js-leetcode 709.To Lower Case.md
- Js-leetcode 771 Jewels and Stones
- Js-leetcode 804.Unique Morse Code Words
- Js-leetcode 867. Transpose Matrix
- Js-leetcode 905. Sort Array By Parity
- Js-leetcode 914. X of a Kind in a Deck of Cards
- Js-leetcode 922. Sort Array By Parity II
- Js-leetcode 1221. Split a String in Balanced Strings
- Js-leetcode 3. Longest substring without repeating characters
- document
- 刘宇波老师--基础知识
- 算法与数据结构
- 数据机构与算法介绍
- 二叉树
- 堆
- 链表
- 队列
- 并查集
- 最小生成树
- 图论
- 最短路径
- 总结
- 玩转数据结构
- 介绍
- 数组
- 栈和队列
- 玩转链表
- 链表与递归
- 二分搜索树
- 集合与映射
- 第8章 优先队列和堆
- 第9章 线段树
- 第10章 Trie
- 玩转算法面试 leetcode题库分门别类详细解析
- 第一章 介绍
- 第二章 时间复杂度和空间复杂度
- 第三章
- 深度实战玩转算法
- JS数据结构与算法
- 第一章.介绍
- 第二章.字符串
- 第三章.数组
- 第四章
- 第五章.排序
- 第六章.递归
- 第七章.栈
- 第八章.队列
- 第九章.链表
- 第十章.矩阵
- 第十一章.二叉树
- 第十二章.堆
- 极客时间
- 第01课丨数据结构与算法总览
- 第02课丨训练准备和复杂度分析
- 第03课丨数组、链表、跳表
- 第04课丨栈、队列、优先队列、双端队列
- 算法基础
- 哈希表(散列表)
- 异或运算
- leetcode
- KD树(K-Dimension Tree)
- Rtree
- B站-左神
- 一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解
- 简单的排序算法
- 认识Nlog(N)的算法
- 第三节:桶排序及排序算法总结
- 左程云算法课程
- 1 认识复杂度、对数器、二分法与异或运算
- 2 链表结构、栈、队列、递归行为、哈希表和有序表
- 10道BAT必问算法面试题
- 超级水王问题
- 78节
- 04链表