汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 Y=?{TX=6<[
[ r
include <iostream> |P`b"x
#include <stdlib.h> }Xfg~%6
~f"3Wa*\B
#ifdef _WIN32 &xA>(|a\&-
using namespace std; vxOnv8(
#endif (E7"GJ
&nwS7n1eb
static void hanoi(int height) EIfqRRTA
{ ]#W7-Q;]
int fromPole, toPole, Disk; /q}(KJX
int *BitStr = new int[height], //用来计算移动的盘的号码 m(o`;
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 { ^^5FE)%
char Place[] = {'A', 'C', 'B'}; OQ4Pk/-'
int i, j, temp; q%QvBN
`\|tXl.
for (i=0; i < height; i++) [oXSjLQm[
{ 'IFA>}e7W
BitStr = 0; _`gkYu3R+
Hold = 1; Ijap%l1I
} fj/L)i
temp = 3 - (height % 2); //第一个盘的柱号 @3$ I
int TotalMoves = (1 << height) - 1; JZ+6)R
for (i=1; i <= TotalMoves; i++) T+aNX/c|>
{ $gN\%X/n"1
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 4_ypFuS ^
{ [VqiF~o,
BitStr[j] = 0; Wp+lI1t
} @$!6u0x
BitStr[j] = 1; O2?yI8|Jn
Disk = j+1; o.w/?
if (Disk == 1) SP/b4
{ y10W\beJ
fromPole = Hold[0]; m mZP;
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 h Ypj
temp = fromPole; //保存上一次从哪个柱子移动过来的 k=mLcP
} tzfyS#E
else B9[vv;lzu
{ ,X1M!'
fromPole = Hold[Disk-1]; (X-(
WMsqQ
toPole = 6 - Hold[0] - Hold[Disk-1]; ]f?r@U'AS|
} 7)[2Ud8
cout << "Move disk " << Disk << " from " << Place[fromPole-1] jMCd`Q]K
<< " to " << Place[toPole-1] << endl; q,<l3r In
Hold[Disk-1] = toPole; 6rj iZ%
} }st~$JsV1
} I\1"E y
mtkZF{3Jx
M$Ui=GGq
"U"fsAc#
']fyD3N
int main(int argc, char *argv[]) S.Kcb=;"L
{ j,;f#+O`g
cout << "Towers of Hanoi: " << endl J%|;
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; )/JVp>
cout << "Input the height of the original tower: "; 8t=O=l\
int height; maHz3:
cin >> height;
B9y5NX
hanoi(height); FyWf`XTO
("ix!\1K@
system("PAUSE"); gK;dfrU.8Y
return EXIT_SUCCESS; qoH:_o8ClO
} {5D%<Te
X@}7 #Vt
.a :7|L#a
GM9[ 0+u;
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 qTRP2rH,L&
h.]^ o*DJ
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 SmD#hE[
u{&=$[;
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 7P}l^WX
Jk`Jv;
算法要点有二: kjp~:Bg_(
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范
F):kF_ho
@BjB
Mi,
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 9eq)WI/
W( sit;O
动的盘子编号有确定关系。 :h(3Ep
Ix,b -C~
2、这个盘子往哪个柱子上移。 N0}[&rE 8
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 ;<[!;8
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 /DH`7E
OmZZTeGg1s
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 X]2Ib'(
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 x9\{a
==?%]ZE8
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。