汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 ( 2i{8
0uS6F8x@
include <iostream>
gIcm`5+T
#include <stdlib.h> #B8V2_M
6"_ytqw7
#ifdef _WIN32 rPF2IS(5
using namespace std; XV:icY
#endif U-lN-/=l6
h|XLL|:
static void hanoi(int height) (-esUOB.
{ ]B9Ut&mF;
int fromPole, toPole, Disk; #mH4\s
int *BitStr = new int[height], //用来计算移动的盘的号码 Oh/2$72
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 '{:lP"\,L
char Place[] = {'A', 'C', 'B'}; xQ@gh
( (
int i, j, temp; SD=9fh0l
w$[ck=
for (i=0; i < height; i++) .dl4f"k
{ `Y.Q{5Y
BitStr = 0; ~"i4"Op&
Hold = 1; cA25FD
} LV$`bZ
temp = 3 - (height % 2); //第一个盘的柱号 !&@!:=X,
int TotalMoves = (1 << height) - 1; 46M?Gfd,X
for (i=1; i <= TotalMoves; i++) bs\7 juHt
{ P |kfPohI=
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 nZ~J&QK-
{ >e9xM Gv
BitStr[j] = 0; gukKa
} 4: S-
BitStr[j] = 1; a29rD$
Disk = j+1; $+p4X# _
if (Disk == 1) v= "2p8@F
{ F}{uY(hv"[
fromPole = Hold[0]; A#8Dv&$Pr
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 0Nq6>^
%
temp = fromPole; //保存上一次从哪个柱子移动过来的 EHcgWlTu
} 6YpP/
K
else D?}K|z LQ
{ EmubpUS;
fromPole = Hold[Disk-1]; H\@@iK=
toPole = 6 - Hold[0] - Hold[Disk-1]; iBy
^
} @#KZ2^
cout << "Move disk " << Disk << " from " << Place[fromPole-1] %Astfn(U{4
<< " to " << Place[toPole-1] << endl; [+z*&~'
Hold[Disk-1] = toPole; 6qkMB|@Ix
} $(ei<cAV
} R,KoymXP
LGF5yRk
qo62!q
M_EXA _
g=_@j`
int main(int argc, char *argv[]) >Mc,c(CvU
{ P q)C(Z
cout << "Towers of Hanoi: " << endl d6;"zW|Ec
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; >Sua:Uff
cout << "Input the height of the original tower: "; D}6~2j
int height; CiTjRJ-ZW)
cin >> height; pv){R;f
hanoi(height); `w/`qG:dK
GV(@(bI*
system("PAUSE"); DSc:>G
return EXIT_SUCCESS; p:CpY'KV_
} z 2Rg`1B
)TV{n#n
R3ru<u>k&
sqP (1|9
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 1*ui|fuK
<zh N7="
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 C
lekB
Mo_(WSs
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 "0#d F:qt
H:>i:\J/M9
算法要点有二: 1.y|bB+kB
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 K`#bLCXEV0
:{ Q[kYj
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 ";$rcg"%X
qZ|>{^a*
动的盘子编号有确定关系。 @ob4y
( zL(
2、这个盘子往哪个柱子上移。 }[m,HA<j
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 tNbZ{=I>
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 z~y=(T
:q,tmk h
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 gS$?#!f
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 R@Kzdeo
2%*mL98WK
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。