0%

汉诺塔问题与递归的思路总结

说明

递归问题一直是笔试的重点,下面开始简单总结递归的问题,主要是递归思考的思路,还有就是怎么用编程的方式来实现。

示例

经典的汉诺塔问题就是最好的递归例子,早期相信很多的手机上面也有这个小游戏吧,就是移动圈圈的问题。以三个圈圈移动为例P1.1

递归主要的思路就是找到 n 和 n-1 步的规律,还有就是递归停止的条件。在这个汉诺塔中,显然,n=1就直接移动过去了,主要是关于数量较多的时候的规律。

首先是移动的函数move,写函数的主要思路是A通过B移动到C,这个一定要理解出来:

1
2
3
4
5
6
void move(int n, char c1, char c2, char c3)
{
if(n == 1)
printf(" %c -> %c \n", c1, c3);
// 暂时没写完,后面还有
}

其次是分析规律,汉诺塔的方式其实还比较简简单,就是先将 n-1 行移动到 B,然后将第 n 行移动到 C,最后将 B 上面的 n-1 行移动到 C 即可。具体如下(很抱歉公式编辑器出来的式子好像有点麻烦在这里显示不出来就用图片来代替了):
图片名称

如实就可以写完整的函数了,如下:

1
2
3
4
5
6
7
8
9
10
11
void move(int n, char c1, char c2, char c3)
{
if(n == 1)
printf(" %c -> %c \n", c1, c3);
else
{
move(n-1, c1, c3, c2);
move(1, c1, c2, c3);
move(n-1, c2, c1, c3);
}
}

实际使用中只需要调用move函数即可,如下:

1
2
3
4
5
6
int main(void)
{
move(5,'A', 'B', 'C');

return 0;
}

总结

递归问题其实是一个常用的思路,但是由于其资源的耗费很多,而且堆栈资源的实用巨大,导致在牛客或者力上面扣做题实用递归常常会可能时间太长了。

结论:在实际使用中如果能用循环解决一定不要用递归!

-------------本文结束感谢您的阅读-------------