汉诺塔算法
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
个人理解:copy一个从大到小排序好的堆栈(堆栈最底层为最大,即先进为最大),且每次出栈的数字数量只能为一个并且需置入另外的从大到小的堆栈内。
思路:堆栈先进后出,而从大到小的顺序注定不能让其从一个堆栈直接进入另一个堆栈,需要另外一个工具堆栈存放必须放置的出栈数字。
如果不考虑必须按大到小存放在工具堆栈与只能一次出栈一个数字的状态下,就是先将所有的数字出栈然后依次置入目标栈堆里。
假设有n个盘子,第一步我们就是要把最大的盘子放在目标柱上,n-1个盘子放在工具柱上。n-1个盘子继续拆分为n-2个盘子和1个盘子,n-2个盘子放在工具柱上,第二大的盘子放在目标柱上。
但是汉诺塔算法的逻辑是第一步我们就是要把最大的盘子放在目标柱上,n-1个盘子放在工具柱上。然后直接把n-1个盘子放在目标柱。
解决办法:从最终求解到最初,递归是很好的算法。
算法实现:
1.粗略算法逻辑
solve(int n)
{
solve(n-1);//解决n-1个盘子
pull(1);//拿出最大的盘子
}
2.加上a,b,c柱
solute(int n,a->b)
{
solute(n-1,b->a);
pull(1,b->c);
}
solute(int n,b->a)
{
solute(n-1,a->b);
pull(1,a->c);
}
3.正式代码:
public class solute {
public void solution(int n,char a,char c,char b)
{
if(n==1)
{
System.out.println("第"+n+"块由"+a+"柱放入"+c+"柱");
return;
}
solution(n-1,a,b,c);
System.out.println("第"+n+"块由"+a+"柱放入"+c+"柱");
solution(n-1,b,c,a);
}
public static void main(String[] args) {
int n=3;
solute s=new solute();
char a='a';
char b='b';
char c='c';
s.solution(n, a, c, b);
}
}
本人不知这个突然的逻辑的转弯是怎么想到的,究竟是就应该这样转弯想,还是说其中有其他更丝滑的逻辑顺理到这个步骤的。
希望能有大佬为我解惑。
这一篇自我学习的文章。