汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 Ik(TII_
%7z
include <iostream> f'TdYG
#include <stdlib.h> =uIu0_v
9^c\$"2B
#ifdef _WIN32 39BGwKXb
using namespace std; khyn4
#endif w<tr<Pu'
pEw &i
static void hanoi(int height) RiIJ#:6+^I
{ Ck/4hZ
int fromPole, toPole, Disk; 3;>|*(cO
int *BitStr = new int[height], //用来计算移动的盘的号码 l{E+j%
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 5kofO
char Place[] = {'A', 'C', 'B'}; oost}%WxN
int i, j, temp; 8m2-fuJz
=ugxPgn
for (i=0; i < height; i++) RL[?&L$7^%
{ ?sdVd
BitStr = 0; tz6d}$
Hold = 1; x3MV"hm2
} 8~u#?xs6
temp = 3 - (height % 2); //第一个盘的柱号 ry/AF
int TotalMoves = (1 << height) - 1; =O<Ul~JRK
for (i=1; i <= TotalMoves; i++) +q|2j>k@
{ W52AX.Nm
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 mh2t ' O
{ ?*tb|AL(R
BitStr[j] = 0; u0Fu_Rtr
}
pBG(%3PpW
BitStr[j] = 1; `s Az1/N
Disk = j+1; x%jJvwb^|
if (Disk == 1) `u3to{
{ $,bLK|<hi
fromPole = Hold[0]; p%jl-CC1
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 7^A;.x
temp = fromPole; //保存上一次从哪个柱子移动过来的 Bq#?g@V
} weEmUw Z
else rLw,?
{ Ont4-AP
fromPole = Hold[Disk-1]; 9_n!.zA<
toPole = 6 - Hold[0] - Hold[Disk-1]; i<YatW~Pu
} |-bSoq7t
cout << "Move disk " << Disk << " from " << Place[fromPole-1] cP''
<< " to " << Place[toPole-1] << endl; #Wey)DI
Hold[Disk-1] = toPole; b?hdWQSW7
} 7q<I7Wt
} QU2\gAM
np}F [v
T9osueh4
Hc ]/0:
K{%}kUj>
int main(int argc, char *argv[]) ]s?BwLU6
{ H-K,Q%;C@
cout << "Towers of Hanoi: " << endl ;H9d.D8
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; :<YcV#!P
cout << "Input the height of the original tower: "; >?ZH[A
int height; h3$.`
>l
cin >> height; 3)^-A4~E
hanoi(height); {.GC7dx
)@DH&
system("PAUSE"); p6$ QTx
return EXIT_SUCCESS; z_~5c
} UN>!#Ji:$
snT! 3t
+R@5e+auQ.
K'+GK S7.
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 *Em 9R
[ Lt1OdGl
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 .iNPLz1
AF g*
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 w4H3($
K
_Pjo9z
9
算法要点有二: (1T2?mO
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 qba<$
T]l_B2.
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 yd2v_
3/RmJ`c{
动的盘子编号有确定关系。 ;aExEgTq
wXIsc;
2、这个盘子往哪个柱子上移。 6TvlK*<r=
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 e; 5n.+m
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 `VCU`Y
^} P|L
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 4#MvOjA5[
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 2cY7sE068
TK<~(Dk
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。