汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 -z1o~~
baG I(Dk
include <iostream> <QLj6#d7Y
#include <stdlib.h> Ll48)P{+}V
<)rH8]V
#ifdef _WIN32 ?KW?] o
using namespace std; P"<ad
kr
#endif :\We =oX
XaSl6CH
static void hanoi(int height) sOenR6J<$
{ h0}-1kVT^
int fromPole, toPole, Disk; @cNI|T
int *BitStr = new int[height], //用来计算移动的盘的号码 sM[c\Z]
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 T8
/'`s
char Place[] = {'A', 'C', 'B'}; ]2
N';(R
int i, j, temp; oD`BX
FQ^uX]<3j
for (i=0; i < height; i++) C.p*mO&N
{ ?q`mr_x%?
BitStr = 0; .1M>KRSr,
Hold = 1; q\Z1-sl~s
} Gl9 a5b
temp = 3 - (height % 2); //第一个盘的柱号 \/zS@fz
int TotalMoves = (1 << height) - 1; Pw1H)<X
for (i=1; i <= TotalMoves; i++) Cvy;O~)
{ 1N*~\rV*?
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 ypVr"fWB
{ :6{HFMf"
BitStr[j] = 0; 2Ta F7Jn
} ^ jA}*YP
BitStr[j] = 1; RzRLrfV
Disk = j+1; r?*?iw2g
if (Disk == 1) p%'((!a2
{
1Btf)y'
fromPole = Hold[0]; beoMLHp
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 7#QH4$@1P
temp = fromPole; //保存上一次从哪个柱子移动过来的 Dr609(zg^
} 7ac3N
else 4mg&H0 !
{ FT6cOMu
fromPole = Hold[Disk-1]; yE>DQ *
toPole = 6 - Hold[0] - Hold[Disk-1]; I+SL0
} TB\CSXb
cout << "Move disk " << Disk << " from " << Place[fromPole-1] F9" K
<< " to " << Place[toPole-1] << endl; ~XRr }z_Lq
Hold[Disk-1] = toPole; ;MD{p1w
} @VAhmYz
} k:.c(_2M
Sl#XJ0 g
B HYEd}M
^C{a'
XDF",N)
int main(int argc, char *argv[]) gg9W7%t/
{ n:+MNr
cout << "Towers of Hanoi: " << endl ;I0/zeM%
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; }e$);A|
cout << "Input the height of the original tower: "; mB\|<2
int height; (;h\)B!o
cin >> height; 1/HZY0em
hanoi(height); KqQrxi?f-
w pvaTHo
system("PAUSE"); Jor?;qo3
return EXIT_SUCCESS; .:0nK
bW
} RK0IkRXQd
~zx-'sc?
mAMKCxz,
]iPdAwc.1
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 Y!H"LI
q0}LfXql8
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 wJ}8y4O!N
~kL":C>2
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 V}*b^<2o5
.Qaqkb-Ty
算法要点有二: -4;u|0_
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 AjpQb~\
{`: !=
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 XjC+kH
SE\`JGA[
动的盘子编号有确定关系。 wo/H:3^N
h*Ej}_
2、这个盘子往哪个柱子上移。 ~ rRIWfhb
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 @!-= :<h
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 "371`!%
-Fb/GZt|
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 |Q{ l]D
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 "_^FRz#h
_K8-O>I "
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。