汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 X[w]aJnAr
M!gu`@@}F
include <iostream> n3U|
d+
#include <stdlib.h> 4J=6U&b
JCZ&TK
#ifdef _WIN32 nHXPEbq-g
using namespace std; /:\27n
#endif 4UW)XLu6T7
6=Q6J
static void hanoi(int height) Ax@7RJ||
{ Q9p2.!/C1
int fromPole, toPole, Disk; kMEXg zl
int *BitStr = new int[height], //用来计算移动的盘的号码 3ErV" R4"$
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 5?(dI9A"K
char Place[] = {'A', 'C', 'B'}; <H<Aba9\
int i, j, temp; WyQ8}]1b
,_7m<(/f
for (i=0; i < height; i++) X>yE<ni
{ {~g7&+9x*
BitStr = 0; Z!'kN\z
Hold = 1; g?j^d:
} l)DcwkIG
temp = 3 - (height % 2); //第一个盘的柱号 6oq^n
s-
int TotalMoves = (1 << height) - 1; "J}B
lB
for (i=1; i <= TotalMoves; i++) ~% ]V,-4
{ u0[O /G
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 SZ4@GK
{ ,@N.v?p>
BitStr[j] = 0; MD4mh2
} ]5ibg"{S
BitStr[j] = 1; WoSKN7*
Disk = j+1; hD,^mru
if (Disk == 1) nddCp~NX
{ 0T$ `;~
fromPole = Hold[0]; \b)P4aL
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 RJT55Rv{
temp = fromPole; //保存上一次从哪个柱子移动过来的 l9y %@7
}
#^-'q`)
else
~xPetkl@
{ Qd?S~3XT
fromPole = Hold[Disk-1]; y^{4}^u-^
toPole = 6 - Hold[0] - Hold[Disk-1]; \j
we
} 0U.Ld:
cout << "Move disk " << Disk << " from " << Place[fromPole-1] @JP6F[d
<< " to " << Place[toPole-1] << endl; #=m:>Q?%z
Hold[Disk-1] = toPole; RdpOj >fT
} NLgeBLB
} `q\v~FT
lY[1P|]
j6 _w2
]8cD, NS
1&=2"
int main(int argc, char *argv[]) rX`fjS*C
{ P=9sP:[f6
cout << "Towers of Hanoi: " << endl F*:H&,
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; 9/#b1NGv
cout << "Input the height of the original tower: "; geqx":gpx9
int height; `I|Y7GoUO
cin >> height; fv>Jn`
hanoi(height); * _,yK-et
j_zy"8Y{
system("PAUSE"); 73nmDZO|
return EXIT_SUCCESS; dW^#}kN7V
} ~ :B/`1[m
= j
l(Q
IeIv k55
lrMkp@f.
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 d;r,?/C
Z\)P|#L$
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 yW"}%)
d
;:)u
rI?
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 6H|T )
WCI'Kh
算法要点有二: %+
MYg^
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 |ew:}e: k<
" M&zW&
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 {N-*eV9#
M|$A)D1
动的盘子编号有确定关系。 D@iS#+22
U[@B63];0
2、这个盘子往哪个柱子上移。 n2(\pQKm
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 =G rg
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 kw1Lm1C
]RW*3X
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 t 9.iWIr
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 2l8z/o 7v
i}5+\t[Q
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。