汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 DC5^k[m
E;m-^dxc
include <iostream> n@`:"j%s_
#include <stdlib.h> /jtU<uX
v{T%`WuPRf
#ifdef _WIN32 s_p\
bl.
using namespace std; [|&V$
#endif 9c}mAg4
`L=d72:
static void hanoi(int height) [@PD[-2QG3
{ >,&@j,?']
int fromPole, toPole, Disk; o-f;$]yp>
int *BitStr = new int[height], //用来计算移动的盘的号码 ==?!z<I.d
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 |BC/ERms
char Place[] = {'A', 'C', 'B'}; C=sEgtEI
int i, j, temp; =u.jZ*u]WT
w`Ss MI
for (i=0; i < height; i++) ZITic&>W
{ u@{z
xYn
BitStr = 0; JJ+A+sfdk
Hold = 1; )qL UHE=
} 4^jIV!V
temp = 3 - (height % 2); //第一个盘的柱号 gpe/ dfyJ9
int TotalMoves = (1 << height) - 1; y-/,,,r
for (i=1; i <= TotalMoves; i++) l0&Y",vy
{ GlPd)m`
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 xX5EhVR
{ )v+R+3<
BitStr[j] = 0; &>T7]])
} dYn<L/#
BitStr[j] = 1; *wd@YMOP
Disk = j+1; xaSg'8-
if (Disk == 1) ]((Ix,ggP
{ _Z>I"m
fromPole = Hold[0]; {j!jm5
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 ?e. Ge0&
temp = fromPole; //保存上一次从哪个柱子移动过来的 O
#
} !/qQ:k-.
else &l0-0T>
{ FB\lUO)U\c
fromPole = Hold[Disk-1]; 6zf3A:]&{
toPole = 6 - Hold[0] - Hold[Disk-1]; 6HK
dBW$/
} 1\{_bUZ&
cout << "Move disk " << Disk << " from " << Place[fromPole-1] Bw`7ND}&
<< " to " << Place[toPole-1] << endl; W7
.Y`u[
Hold[Disk-1] = toPole; \H-,^[G3
} q"uP%TN
} RY4b<i3
&W|r
P(
g:yUZ;U
5x}XiMM
))<1"7D^^
int main(int argc, char *argv[]) kYl')L6
{ NF0=t}e
cout << "Towers of Hanoi: " << endl v1m'p:7uGB
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; w9c^IS
cout << "Input the height of the original tower: "; 97]$*&fH
int height; qVidubsW
cin >> height; n-5@<y^
hanoi(height); rZt7C(FM$7
-{=c T?"+
system("PAUSE"); e+? -#
return EXIT_SUCCESS; WbP
wO
} .R<Ke\y/
R'Y=-
yF
u[>hs
\3k
]-D&/88``
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 5Y W.s
YO3$I!(
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 P\3$Y-id
9_07?`Jr
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 CB1AL]|3
jr=>L:
算法要点有二: (oiF05n
h
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 i=ztWKwKf
t]QGyW A]
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 K~MTbdg
.Y^UPxf@
动的盘子编号有确定关系。 - 2`D(xC
'(4#He?Gd
2、这个盘子往哪个柱子上移。 D{J+}*y
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 v)VhR2d3
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 </%n:<z4
mH/$_x)o
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 j_I
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 @|1/yQgi
*
I{)8
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。