汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 ~e,D`Lv
me+F0:L
include <iostream> &3SQVOW ~T
#include <stdlib.h> 8e`'Ox_5a
2&f]v`|M|
#ifdef _WIN32 l.#iMi(@p~
using namespace std; *<PQp
#endif $R '
cZ@z]LY.g
static void hanoi(int height) Yy$GfjJtL]
{ Vd-\_VP20
int fromPole, toPole, Disk; b#:Pl`n6u
int *BitStr = new int[height], //用来计算移动的盘的号码 }E\ b_.
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 p@H3NX
char Place[] = {'A', 'C', 'B'}; cBl
F
int i, j, temp; ^=H. .pr
JP2zom
for (i=0; i < height; i++) "pDwN$c
{ FZW)C'j
BitStr = 0; FJ|6R( T_
Hold = 1; cK;,=\
} pohA??t2:
temp = 3 - (height % 2); //第一个盘的柱号 SD "'
int TotalMoves = (1 << height) - 1; 7>Af"1$g
for (i=1; i <= TotalMoves; i++) u*I=.
{ TV~<1vj
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 MT8BP)C
{ x:h0/f
BitStr[j] = 0; D5wy7`c
} kjo,?$r
%
BitStr[j] = 1; A/XY'3
Disk = j+1;
p97}HT}
if (Disk == 1) jm_b3!J
{ wF +9Iu
fromPole = Hold[0]; tFY;q##z
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 >IL[eiiPG
temp = fromPole; //保存上一次从哪个柱子移动过来的 K8sgeX|
} na;U]IK
else {&2aH>V/
{ Q-3o k7
fromPole = Hold[Disk-1]; h}X^
toPole = 6 - Hold[0] - Hold[Disk-1]; ? 1OZEzA!
} /B$9B
cout << "Move disk " << Disk << " from " << Place[fromPole-1] `aj;FrF
<< " to " << Place[toPole-1] << endl; 7X
h'VOljB
Hold[Disk-1] = toPole; J33enQd
} 3;wAm/Z:Q
} }r}$8M+1
}tvLe3O
l\PDou@5
j4ARGkK5B
MeXzWLH
int main(int argc, char *argv[]) bbDl?m&bq
{ GOT@
cout << "Towers of Hanoi: " << endl (v11;k dJB
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; OJ (ho&((
cout << "Input the height of the original tower: "; Ow0-}Im~
int height; wA+QUN3#n
cin >> height; (]JZ1s|
hanoi(height); ^x Wu7q
Vv"JN?dHi
system("PAUSE"); aZ[
aZU
return EXIT_SUCCESS; 1:7 uS.
} +d7sy0
n+C]&6-b
qSB]Zm<
HLL[r0P`F
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 'W!N1W@
8oM]gW;J~
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 ?-40bb
|\yVnk!c
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 9n#Q1Xq
G~SgI>Q
算法要点有二: [^rT: %Z
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 X@;o<2^
v8
Q/DJ~
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 MIblx
^6tcB* #A
动的盘子编号有确定关系。 l98.Hb7
huMNt6P[
2、这个盘子往哪个柱子上移。 fOE8{O^W
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。
X2X.&^
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 5H (CP
dKs^Dq
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 C$9+p@G6
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 ,QDS_u$xi&
r-27AJu
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。