汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 pipqXe
+9[s(E?SY
include <iostream> KSB{Z TE
#include <stdlib.h> qJq2Z.>hy
.vk|aIG
#ifdef _WIN32 _S3qPPo3l]
using namespace std; =.yKl*WV{
#endif %2z]2@
q8[I`
V{
static void hanoi(int height) =x^b
{ i2Cw#x0s
int fromPole, toPole, Disk; ;.|).y1/`
int *BitStr = new int[height], //用来计算移动的盘的号码 Gk2R:\/Y
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 _NkbB"+L
char Place[] = {'A', 'C', 'B'}; VmTPE5d
int i, j, temp; '
Y cVFi
$*z>t*{7
for (i=0; i < height; i++) #t?tt,nc}
{ -$+`v<[r
BitStr = 0; Avr2MaY{h
Hold = 1; ZI NqIfc
} L0dj 76'M
temp = 3 - (height % 2); //第一个盘的柱号 =#K$b *#
int TotalMoves = (1 << height) - 1; `2.2; Vk
for (i=1; i <= TotalMoves; i++) k-XE|v
{ n2(@uT&>
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 <j^bk"l p
{ ?R8wm E[w
BitStr[j] = 0; 8oVQ:' 6
} q;L~5q."E
BitStr[j] = 1; P/;d|M(
Disk = j+1; y;1l].L
if (Disk == 1) jce^Xf
{ flzHZH
fromPole = Hold[0]; d/!R;,^
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 |A% Jx__
temp = fromPole; //保存上一次从哪个柱子移动过来的 'v:%} qMv
} 9e>Dqlv
else LJ+Qe%|
{ mOE%:xq9-
fromPole = Hold[Disk-1]; F3pBk)>a\
toPole = 6 - Hold[0] - Hold[Disk-1]; ">hOD'PG
} b%"Lwqdr7
cout << "Move disk " << Disk << " from " << Place[fromPole-1] TX7]$Wj
<< " to " << Place[toPole-1] << endl; Cp[
NVmN
Hold[Disk-1] = toPole; j&
~`wGM
} Kb5 Y A
} M^3pJ=;5
%YbcI|i]<0
RJO40&Z<Z
v cZg3:j
fBRU4q=^T
int main(int argc, char *argv[]) B`i5lD
{ q#!]5
cout << "Towers of Hanoi: " << endl k7\
,No}
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; @$ggPrs
cout << "Input the height of the original tower: "; AHl1{*
[
int height; "Acc]CqH*
cin >> height; 7GVI={b
hanoi(height); /swNhDQ"o
di5>aAJ)D
system("PAUSE"); N6wCCXd
return EXIT_SUCCESS; =vc8u&L2
} `R+I(Cb
4A@77#:J5
/yn%0Wish
!&b
wFO>P
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 .,$<waGD
]|PDsb"e
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 1?j['~aE
@x@*=
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 Fo@cz"%
<JNiW8 PG
算法要点有二: jt? .g'
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 /;rPzP4K6
l6O8:XI
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 Vim*4^[#L
|A0)-sVZ
动的盘子编号有确定关系。 8BgHoQ*
'|JBA.s|
2、这个盘子往哪个柱子上移。 1{pU:/_W
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 #y:,owo3I
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 m_pqU(sP
- IF3'VG
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 SV}C]<
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 %zCV>D
,2C{X+t
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。