汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 +z jzO]8
t2-nCRXEP
include <iostream> k`7.p,;}U
#include <stdlib.h> zUEfa!#?
4=F]`Lql
#ifdef _WIN32 `\|3
~_v
using namespace std; KB,~u*~!
#endif @Uj_+c
q
t1:S!@
static void hanoi(int height) 4'{hI;&a&
{ 3^A/`8R7K
int fromPole, toPole, Disk; jRdhLs,M9
int *BitStr = new int[height], //用来计算移动的盘的号码 i9@;,4f
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 b ?2X>QJ
char Place[] = {'A', 'C', 'B'}; ;+ Co!L
int i, j, temp; ^0-e,d
9h
3dxnh,]&@
for (i=0; i < height; i++) yrE,,N%I
{ F'UguC">
BitStr = 0; Dmm r]~
Hold = 1; ,+NE: _
} tgvpf/cQ
temp = 3 - (height % 2); //第一个盘的柱号 bco[L@6G$
int TotalMoves = (1 << height) - 1; @RoRNat
for (i=1; i <= TotalMoves; i++) 0(hv #C4
{ orQV'
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 n<%=~1iY+
{ *t?~)o7
BitStr[j] = 0; J+cAS/MYX
} SZK)q
BitStr[j] = 1; 4gv.E 0Fo
Disk = j+1; yYG3/Z3u5
if (Disk == 1) d#vSE.&
{ 94h_t@Q/1
fromPole = Hold[0]; u_p7Mcb
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 |`k1zc)9
temp = fromPole; //保存上一次从哪个柱子移动过来的 RvPniT(<?
} PV]k3&y
else w$b+R8.n)
{ y=oVUsG
fromPole = Hold[Disk-1]; oc3dd"8}@
toPole = 6 - Hold[0] - Hold[Disk-1]; l6S19Kv
} *< $c
=
cout << "Move disk " << Disk << " from " << Place[fromPole-1] re ]Ste
<< " to " << Place[toPole-1] << endl; PzMlua
Hold[Disk-1] = toPole; u8<&F`7j
} ;*wT,2;
} ^EC)~HP@C
`bZ2x@
z|G|Y 22
jHu,u|e0>S
E~<(i':
int main(int argc, char *argv[]) &Hlm{FHU
{ 7z/(V\9B
cout << "Towers of Hanoi: " << endl +(=0CA0GE
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; +3/k/W
cout << "Input the height of the original tower: "; *w'q
int height; Q3NPwM
cin >> height; DnG/ n
hanoi(height); &O+sK4P
.Ca"$2
system("PAUSE"); 8 l'bRyuS
return EXIT_SUCCESS; D0Vyh"ua
} H9Y2n 0
H-/; l54E
6m, KL5>W
[]A"]p
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 ]k::J>84
?AeHVQ
:C
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 z`emKFbv
>%uAQiU
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 :rz9M@7
p4m^ ~e
算法要点有二: 1a($8>
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 ,2 zt.aqB
`G=ztL!gq
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 H4PbO/{xO
toS(UM n
动的盘子编号有确定关系。 Q vv\+Jp^
3W7;f!
2、这个盘子往哪个柱子上移。 krQl^~@
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 <mv7HKVg
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 Je#!Wd
#dva0%-1
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 /<3;0~#){
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 j!zA+hF(
YMc8Q\*B
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。