汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 lM-*{<B
\Yd
0oe82
include <iostream>
e&J_uG
#include <stdlib.h> P V,AN
/f)
#CR0$
#ifdef _WIN32 $yg=tWk
using namespace std; <<.%Gk
#endif \cRe,(?O
Y+'522er
static void hanoi(int height) Tx\g5rk
{ SebJ}P1x
int fromPole, toPole, Disk; uw`fC%-xh
int *BitStr = new int[height], //用来计算移动的盘的号码 p$*;>YKO
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 u.Z,HsEO b
char Place[] = {'A', 'C', 'B'}; S2*ER
int i, j, temp; bem-T`>'
T&PLvyBL
for (i=0; i < height; i++) Du."O]syD
{ &i%1\o
BitStr = 0; aj)?P
Hold = 1; rc9Y:(S1l
} 2>!?EIE7
temp = 3 - (height % 2); //第一个盘的柱号 JDy ;Jb
int TotalMoves = (1 << height) - 1; #J<IHNRt
for (i=1; i <= TotalMoves; i++) eq#x~O4
{ duk:: |{F
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 s.7s:Q`
{ a4L0Itrp
BitStr[j] = 0; 81<0B@E
} 1_z6O!rx
BitStr[j] = 1; I{0bsTp;
Disk = j+1; bR;Zc
if (Disk == 1) _cW6H B^j
{ J$Qm:DC5
fromPole = Hold[0]; &`L5UX
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 vB4cdW
2#3
temp = fromPole; //保存上一次从哪个柱子移动过来的 _R(5?rG,
} J+*rjdI
else QrA8KSLC
{ 3/rvSR!
fromPole = Hold[Disk-1]; uWnS<O
toPole = 6 - Hold[0] - Hold[Disk-1]; L7Oytdc<
} cn\& ;55v
cout << "Move disk " << Disk << " from " << Place[fromPole-1] a3c4#'c|D
<< " to " << Place[toPole-1] << endl; PYHm6'5BtB
Hold[Disk-1] = toPole; M<$l&%<`G
} qfYb\b
} }BogE$tc
j[U0,]
aY:(0en]&
*VlYl"
J$I1*~I4v
int main(int argc, char *argv[]) \[oHt:$do
{ #8z\i2I
cout << "Towers of Hanoi: " << endl fA,+qs
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; fd,~Yj$R?
cout << "Input the height of the original tower: "; E+1j3Q;
int height; CLk Ve
cin >> height; I(<G;ft<}
hanoi(height); PRz oLzr
_@OYC<
system("PAUSE"); BkZ%0rw%
return EXIT_SUCCESS; Nz}Q"6L
} S-/#3
sMS`-,37u
kTk?[BK
JZXc1R| 9
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 2>!ykUw^O
lhI;K4#
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 Kmnr}Lp9
~JNuy"8
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 F:@Ixk?E
+i>q;=~
算法要点有二: <M7*N.
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 tQ~B!j]
u
.2sB6}
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 m%V[&"5%e
DsX>xzM
动的盘子编号有确定关系。 H+;wnI>@
Ax0,7,8y
2、这个盘子往哪个柱子上移。 RrHnDO'
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 ger<JSL%
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 i4I0oRp
Y2X1!Em>B
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 K*Jtyy}r
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 QRlzGRueR&
/=@vG Vp6
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。