汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 WW6-oQs_#*
V*2*5hx
include <iostream> {4/*2IRN9h
#include <stdlib.h> ?#&[1.= u
(vD==n9Hd
#ifdef _WIN32 >m!Z$m([J
using namespace std; 0iR?r+|
#endif 3[_WTwX0
J> ,w},`
static void hanoi(int height) VrfEa d
{ DxN\ H"
int fromPole, toPole, Disk; cc`u{F9
int *BitStr = new int[height], //用来计算移动的盘的号码 /&47qU4PJ
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 wVI_SQ<8V
char Place[] = {'A', 'C', 'B'}; _s0)Dl6K
int i, j, temp; +eH`mI0f
n<FUaR>q}
for (i=0; i < height; i++) }dMX1e1h8
{ V6c8o2G;+
BitStr = 0; h~qvd--p0
Hold = 1; qj:[NPwaM
} 9SA %'
temp = 3 - (height % 2); //第一个盘的柱号 iumwhb
int TotalMoves = (1 << height) - 1; gs i2
for (i=1; i <= TotalMoves; i++) KTmwkZcfYD
{ pnx^a}|px
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 adri02C/
{ H<ovIMd
BitStr[j] = 0; lg
)xQV
} WEG!;XZ
BitStr[j] = 1; %rlqq*
Disk = j+1; SQU@JKi;g
if (Disk == 1) ARnq~E@1
{ $\]Mvd
fromPole = Hold[0]; $39TP@?:Z)
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 Dt7z<1-)l
temp = fromPole; //保存上一次从哪个柱子移动过来的 v)|a}5={
} h\Y~sm?!`
else ]lyQ*gM
{ Glx{Zu=
fromPole = Hold[Disk-1]; 6?.S-.Mr
toPole = 6 - Hold[0] - Hold[Disk-1]; Y^d#8^cP
} +.^pAz U}R
cout << "Move disk " << Disk << " from " << Place[fromPole-1] 4)}>dxv
<< " to " << Place[toPole-1] << endl; l]t^MEoc8
Hold[Disk-1] = toPole; C{t}q*fG
5
} Oi~Dio_?
} G[>CBh5
(yuOY/~k/
P<[)
qq@;
@~7au9.V=X
kt_O=
int main(int argc, char *argv[]) !
,H6.IH;S
{ 1\/vS$bi(
cout << "Towers of Hanoi: " << endl "^{Hta
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; >Q"3dw
cout << "Input the height of the original tower: "; wfu`(4
int height; "B"ql-K
cin >> height; g%^/^<ei
hanoi(height); x@O)QaBN!
lF46W
system("PAUSE"); [z7]@v6b
return EXIT_SUCCESS; iDgc$'%?
} -R];tpddR5
y!S:d
= 4|"<8'
4T$jY}U
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 6q0)/|,@
H0lW gJmi|
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 S_??G:i
b 5K"lPr
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 kDQE*o
l$HBYA\Qh
算法要点有二: MZX@Gi<S[
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 N(J#<;!yb
xi,fm
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 ]JmE(Y1(1
"5N$u(: b
动的盘子编号有确定关系。 yF|28KJ
b rDyjh
2、这个盘子往哪个柱子上移。 Iv9U4
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 9-1'jNV
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 *h5L1Eq
;8e}X6YU
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 %g>k0~TRf#
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 /yUKUXi
/9D
mK%d
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。