汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 bv VkN
C+g}+
include <iostream> m2"wMt"*V
#include <stdlib.h> *V7mM?
Yxbg _RQm
#ifdef _WIN32 ="v`W'Pd
using namespace std; eh>
|m>JY
#endif r}es_9*~Z
YC')vv3o(
static void hanoi(int height) (~o"*1fk>
{ M[~{!0Uz
g
int fromPole, toPole, Disk; 7e\Jg/FU
int *BitStr = new int[height], //用来计算移动的盘的号码 JsNj!aeU%
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 1y\bJ
char Place[] = {'A', 'C', 'B'}; 3&CV!+z
int i, j, temp; :;eQ*{ `\
WMC\J(@.
for (i=0; i < height; i++) T0Xm}i
{ ;i\N!T{>
BitStr = 0; /(*Ucv2i}T
Hold = 1; Wy}^5]R0E
} 3E^qh03(
temp = 3 - (height % 2); //第一个盘的柱号 }79O[&
int TotalMoves = (1 << height) - 1; T~k @Z
for (i=1; i <= TotalMoves; i++) Qrt\bz h/}
{ DxwR&S{
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 1ANFhl(l
{
y*ZA{
BitStr[j] = 0; :"MHmm=uU8
} fgeh;cD
BitStr[j] = 1;
ti (Hx
Disk = j+1; 57EX#:a
if (Disk == 1) 2]Il:>n,
{ tcT=a@
fromPole = Hold[0]; ?_d6;
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 r7oFG!.?
temp = fromPole; //保存上一次从哪个柱子移动过来的 }8"
|q3k
} _dRB=bl"O
else VnVBA-#r|
{ G{]RC^Zo
fromPole = Hold[Disk-1]; Jx~H4y=z
toPole = 6 - Hold[0] - Hold[Disk-1]; .|^Gde
} l)*(UZ"
cout << "Move disk " << Disk << " from " << Place[fromPole-1] |Q%P4S"B?
<< " to " << Place[toPole-1] << endl; V:'F_/&X?
Hold[Disk-1] = toPole; ZnRT$ l O
}
*Z^`H!&
} A&)2m
}oA>0Nw$K
) WbWp4
C1e@{>
U 7.k Yu
int main(int argc, char *argv[]) tE_n>~Zs
{ ;cvMNU$fN
cout << "Towers of Hanoi: " << endl >5#}/G&
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; 2H}y1bkW
cout << "Input the height of the original tower: "; Vx2/^MiXy
int height; E&
i (T2c
cin >> height; in/~' u
hanoi(height); w~)tEN>
S'8+jY
system("PAUSE"); +^+'.xQ
return EXIT_SUCCESS; \c4jGJ
} s{R,- \_
vhbHt_!u&
3 a.!9R>
\?
)S{
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 erW2>^My
/0H}-i
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 Gmi?xGn
J)Y`G4l2@
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 G@#lf@M]
ofV0L
算法要点有二: /uX*FZ
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 D$K'Qk
#p@GhI!6
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 6" * <0
OQ hQ!6
动的盘子编号有确定关系。 T2S_>
#."l
I2WP/
2、这个盘子往哪个柱子上移。 cJaA*sg
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 k:Y\i]#yP
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 $
mE*=
0S$k;q
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 (&Rk#i U
2
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 TLVsTM8P
t&?{+?p:
9
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。