汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 s|TO9N)pO
NGO?K?
include <iostream> 8qxZ7|Y@
#include <stdlib.h> |Z+qaq{X
r>CBp$
#ifdef _WIN32 aMJ2bu
using namespace std; 8=?U7aw
#endif t3K9 |8<
(*V!V3E3#
static void hanoi(int height) ]6O(r)k
{ yF+mJ >kj
int fromPole, toPole, Disk; ZW@cw}
int *BitStr = new int[height], //用来计算移动的盘的号码 Ol|fdQ
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 0I2?fz)
char Place[] = {'A', 'C', 'B'}; 4p6T0II_$
int i, j, temp; M&H,`gm
[
<k&]Kv
for (i=0; i < height; i++) BJ
fBYH,M
{ 5D
XBTpCVM
BitStr = 0; 2=1qmQE
Hold = 1; kqq1;Kd
} s;]"LD@
temp = 3 - (height % 2); //第一个盘的柱号 ?wn<F}UH
int TotalMoves = (1 << height) - 1; OqmW lN.?
for (i=1; i <= TotalMoves; i++) ,6"[vb#*3
{ aOsc_5XDR;
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 %e|UA-(
{ {]N7kY.W
BitStr[j] = 0; +OtD@lD`!
} 1Oak8 \G
BitStr[j] = 1; -SzCeq(p%5
Disk = j+1; G9K& }_,
if (Disk == 1) >enP~uW[#
{ ,_=LV
fromPole = Hold[0]; Z^mQb2e.
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 /BhP`a%2Q
temp = fromPole; //保存上一次从哪个柱子移动过来的 SbsdunW+?
} e:_[0#
else mmCGIX
{ l Ttc#
fromPole = Hold[Disk-1]; C+mPl +}w
toPole = 6 - Hold[0] - Hold[Disk-1]; D}-HWJQA3
} P*hYh5a
cout << "Move disk " << Disk << " from " << Place[fromPole-1] bQI.Qk
<< " to " << Place[toPole-1] << endl; w6^TwjjZ$
Hold[Disk-1] = toPole; (Fq]y5
} oU*e=uehj
} Y ._Om}H
-B-HZ_
.f!:@fX>=
G%h+KTw
7; ?7q
int main(int argc, char *argv[]) f3:dn7
{ RK)ikLgp
cout << "Towers of Hanoi: " << endl |I|,6*)xg
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; KxfH6:\RB
cout << "Input the height of the original tower: ";
9C5F#(uY
int height; ^W^Y"0y9`
cin >> height; ?iHcY,
hanoi(height); r'XWt]B+[
T?`Ha\go
system("PAUSE"); zn|O)"C
return EXIT_SUCCESS; vB5mOXGN q
} 4FKgp|Y0
`q1-yH0~4
#sbW^Q'I
%L-{4Z!"sI
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 fQ_tXY
-Q ];o~
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 Vn_>c#B
WM=)K1p0u
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 $%ww$3
%Rk0sfLvn
算法要点有二: 2o W'B^-
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 tlI]);iE,
*ODc[k'(
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 <UGM/+aO
ygUX ]*m!
动的盘子编号有确定关系。 CL t(_!q
VwarU(*
2、这个盘子往哪个柱子上移。 |t#s h
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 &rc
r>-
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 uF)^mT0D=
``kesz
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 cwQ*P$n
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 6QP T
B>cx[.#!
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。