汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 I4ctxMVP
X#7}c5^Y
include <iostream> z+Z%H#9e
#include <stdlib.h> #nbn K
*+W6 P.K
#ifdef _WIN32 ;"SZ}
using namespace std; `$f2eB&
#endif ##2`5i-x
"B?R|
Xg
static void hanoi(int height) i :EO(`
{ c
_p[yS
int fromPole, toPole, Disk; ooDdV
>
int *BitStr = new int[height], //用来计算移动的盘的号码 A`Q
>h{
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 FdM<;}6T
char Place[] = {'A', 'C', 'B'}; g~|y$T
int i, j, temp; ? KF=W
;,v.(Z ic
for (i=0; i < height; i++) ^f6
{0
{ H.9yT\f.
BitStr = 0; }M?|,N6
Hold = 1; {YBl:rMz
} _y"a2M
temp = 3 - (height % 2); //第一个盘的柱号 p4y6R4kyT
int TotalMoves = (1 << height) - 1; ]p\u$VY9
for (i=1; i <= TotalMoves; i++) 15JsmA*Q
{ <B=[hk!
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 6."PS4}:
{ EqoASu
BitStr[j] = 0; g@}6N.]#
} _ Q{T ';
BitStr[j] = 1; +`9yZOaC#
Disk = j+1; >mew"0Q
if (Disk == 1) KZZOi:
{ bu_/R~&3{
fromPole = Hold[0]; ~@ ?"'!U
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 5'62ulwMP=
temp = fromPole; //保存上一次从哪个柱子移动过来的 tr5'dX4]
} K:uQ#W.&
else f%L:<4
{ %kJh6J
fromPole = Hold[Disk-1]; nZ541o@t9
toPole = 6 - Hold[0] - Hold[Disk-1]; xl|ghjn
} u*U_7Uw$
cout << "Move disk " << Disk << " from " << Place[fromPole-1] A%P 8c
<< " to " << Place[toPole-1] << endl; qT"drgpi3
Hold[Disk-1] = toPole; gu^_iU
} sD2*x T
} r)c+".0d^
Oe/73|
>U
i]LU4y%'
XNKtL]U}$
g(KK9Unu
int main(int argc, char *argv[]) n}VbdxlN
{ %-\FVKX
cout << "Towers of Hanoi: " << endl Y'2-yB
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; kHGeCJe\{
cout << "Input the height of the original tower: "; O(WEgz
int height; mn(/E/
cin >> height; FLK"|*A
hanoi(height); ?ISI[hoc
"k/;`eAP
system("PAUSE"); =!(S<];
return EXIT_SUCCESS; W;q#ZD(;
} %N7gT*B:
eSJAPU(D
-<]\l3E&J
Av@&hD\
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 ;tXB46
]!]`~ Z/
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 =7F E/S
YomwjKyuP
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 ~wa%fM
p
.lu4
算法要点有二: qK{|Q
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 ?OdV1xB
UB5}i('L
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 *iPs4Es-
,:c:6Y^
动的盘子编号有确定关系。 h_AJI\{"
#8S [z5 `
2、这个盘子往哪个柱子上移。 A1mYkG)l
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 f&=K]:WDe
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 jM6uT'Io
!&'# a
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 k,a,h^{}j
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 Lr K9F^c
"1_{c *ck
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。