晚上的时候看了一下递归,汉诺塔算法,没有想通,躺在床上翻来覆去的睡不着,满脑子都是这个123,321,,,,
想着想着就有感觉了,感觉起来写个博客记录一下,我怕明天早上忘记了;
直接上代码,代码中添加了想法和注释:
/**
* 汉诺塔
* 目标:将n个塔片从start利用middle转换至end
* 理解:逆向思维,
* 思想第一步:将n个塔片看成是一个整体,想要把这个整体移动从start移到end
* 只需要直接移动即可 1------3
* 就是我们下面的if(n <= 1) 的代码
*
* 思想第二步:将n个塔片看成是两个部分,下面一个最大的 + 其他的看作是一个整体(n-1)
* 想要将下面最大的从start放在end上,就要将(n-1)放在middle上,就是下面这
* 行代码 hanNuoTa(n-1, start, end, middle);
* 这一步之后剩下的全部在middle上了,将这些看成是A,把A看成是两部分,现存最大的 + (A-1)
* 想要将下面最大的从middle放到end上,就要讲(A-1)放在start上,就是下面这
* 行代码 hanNuoTa(n-1, middle, start, end);
*
* 走到这里发现问题没,剩下的又都回到start上面了,
* 后面发生的事情就是从头开始再进行,直至结束;
*
*/
public static void hanNuoTa(int n, int start, int middle, int end){
if (n <=1){
System.out.println(n + "---------------" +start+ "---->"+end);
} else {
// 这一轮的目标,
// 留一片将其他所有的看成一个整体
// 将这一个整体放在middle上
// 那么留下的一片也就可以直接拿到end上了
// 这一轮结束后,剩下的整体都在middle上了
hanNuoTa(n-1, start, end, middle);
System.out.println("middle开始了------------------n--"+ n + " " + start+"---->"+end);
// 走到这一步骤的时候意味着start上面已经是空的了,end上面已经是拿到最大的了
// 那么就将这看成是一个大塔片加一个整体
// 将这一个整体放在start上
// 那么留下的一片也就可以直接拿到end上了
hanNuoTa(n-1, middle, start, end);
}
}
测试代码
@Test
public void test(){
hanNuoTa(3, 1, 2, 3);
}
不知道汉诺塔的同学可以去查一下,我看一些小视频中小孩子玩的汉诺塔挺好玩的;
希望能帮助到有需要的同学;
希望我也能一直努力坚持下去;