【C语言】汉诺塔问题
之前遇见这个问题,非常费劲地理解了,并写出代码,然后过段时间,再遇见这个问题,又卡住了,如此反反复复两三次,才发现自己对递归的理解依然很肤浅。今天无聊,重温《算法:c语言实现》一书,又遇见了这个问题,心头一紧,担心要费些时间才能写出代码,没想到的是,再理解了书中对递归的定义,蒙住源代码动手写,发现很快就写出来了,甚至都没有费力去模拟整个汉诺塔移动过程,只是根据递归的要领(数学归纳法)分析了一下问题,便得出了一个递归形式,照此写代码,竟然没错。由此也醒悟到,很多时候,用递归写代码并不难,但却常常受困于一种恐惧和自惭的心理而畏葸不前。
下面是源代码,在此之前,阐述一下自己对递归的理解,“对于我们编写的每个递归函数,都必须能够进行有效的归纳证明。”这是《算法:c语言实现》中让我恍然大悟的一句话。这句话的意思是:根据数学归纳的形式,总是能够倒推出完整的递归形式的。数学归纳法的形式非常清晰,其过程通常为先试验初始条件n=1,验证某假设或公理是否成立,再设n=k,假设成立,由n=k推出n=k+1的时候,该假设是否成立。具体分析汉诺塔问题,其最原始的思想是:”从某根桩移动N个盘子到后边桩上,接着以此类推,移动剩下N-1个盘(放在第N个盘上)。“
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 |
#include <stdio.h> #include <stdlib.h> #define ALL 6 enum
DIRECT{left = 1, mid = 2, right = 3}; void
hanoi( int
N, int
pos, int
dst); void
shift( int
N, int
pos, int
direct); int
main() { hanoi(4, left, mid); return
0; } void
hanoi( int
N, int
pos, int
dst) { if ( 0 == N) return
; hanoi(N-1, pos, ALL-dst-pos); shift(N, pos, dst); hanoi(N-1, ALL-dst-pos, dst); } void
shift( int
N, int
pos, int
direct) { printf ( "move %d from pillar %d to pillar %d\n" , N, pos, direct); } |
众所周知,“递归程序总是可以转换成执行相同计算的非递归性程序。” 递归到非递归的转换,由堆栈来实现,此处不再赘述,感兴趣的可以看看这个网站:http://hawstein.com/posts/3.4.html
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。