汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 \`<cH#
MB
ju![n
include <iostream> Qp,DL@mp>8
#include <stdlib.h> `N//A}9
Gc]~wD$
#ifdef _WIN32 mMx ;yZ
using namespace std; !rDdd%Z
#endif D%mXA70
[S]S^ej*8
static void hanoi(int height) tY${M^^<J
{ vr^~yEr
int fromPole, toPole, Disk; q LL,F
int *BitStr = new int[height], //用来计算移动的盘的号码 [H\:pP8t
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 AmPMY:1i"
char Place[] = {'A', 'C', 'B'}; 0kQPJWF
int i, j, temp; jxaD&4Fs8
*_ Z#O,
for (i=0; i < height; i++) #ge)2
{ WO4=Mte?
BitStr = 0; Zv_.na/^K
Hold = 1; _-!sBK+F
} nMfFH[I4
temp = 3 - (height % 2); //第一个盘的柱号 /v|"0
int TotalMoves = (1 << height) - 1; 1(Y7mM8\
for (i=1; i <= TotalMoves; i++) 93qwH%
{ iB0WEj[?
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 ,r^M?>
{ u?Tpi[
#
BitStr[j] = 0; @RFs/'
} \I-#1M
BitStr[j] = 1; uJHu>M}~
Disk = j+1; iI@jZVk
if (Disk == 1) 02`$OTKz
{ v8gdU7Ll,
fromPole = Hold[0]; p^nL&yIW,%
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 E9|eu\
temp = fromPole; //保存上一次从哪个柱子移动过来的 4h!f/aF'
} ,/&'m13b/L
else t>GfM
{ (bOpV>\Q7
fromPole = Hold[Disk-1]; Z@8vL
toPole = 6 - Hold[0] - Hold[Disk-1]; o@]So(9f
} o*x*jn:hm
cout << "Move disk " << Disk << " from " << Place[fromPole-1] 2$_9cF Wm
<< " to " << Place[toPole-1] << endl; ^,F;M`[
Hold[Disk-1] = toPole; `~eX55W
} b `2|I {
} c^rOImZ
M/?KV9Xk2
9odJr]
{8,<ZZ_
5(W"-A}
int main(int argc, char *argv[]) J89Dul l
{ n?\ nn3
cout << "Towers of Hanoi: " << endl Mypc3
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; &R|/t:DN
cout << "Input the height of the original tower: "; M<SdPC(+
int height; &1l=X]%
cin >> height; Iz6y{E
hanoi(height); L%v^s4@
,uw132<b
system("PAUSE"); PkE5|d*,
return EXIT_SUCCESS; SvN9aD1
} _LAS~x7,
wiaX&-c]8
IM$2VlC
<2!v(EkI
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 >{eCh$L
g~7Ri-"
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 e__@GBG
Ftw;Yz
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 >e2<!#er|
E ca\fkj
算法要点有二: $Y=T&O
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 :+{ ?
,*4p?|A
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 {GvTfZfp
V._6=ZJ
动的盘子编号有确定关系。 X1IeSMAe
}?cGf-c
2、这个盘子往哪个柱子上移。 tt%MoQ)
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 +jg9$e "
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 JOjoiA
ky
8e p
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 ml@2wGyf
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 ,BF E=:ZIK
"fg](Cp[z
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。