汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 !xvAy3
F4PWL|1
include <iostream> #Q` TH<
#include <stdlib.h> TpcJ1*t
QjOY1Xze
#ifdef _WIN32 MSE0z!t
using namespace std; {t!Pv2y<
#endif S S fNI>
d<RJH
static void hanoi(int height) w@WPp0mny
{ Fv<3VKueK[
int fromPole, toPole, Disk; _N:GZLG
int *BitStr = new int[height], //用来计算移动的盘的号码 UM2yv6:/
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 =[,EFkU?B
char Place[] = {'A', 'C', 'B'}; apjoIO-<
int i, j, temp; hc*t Q2
2Mu@P8O&
for (i=0; i < height; i++) 08+\fT [
{ 5,J.$Sax
BitStr = 0; bbT1p:RF
Hold = 1; 0BQ{ZT-Kh
} >i"WKd=
temp = 3 - (height % 2); //第一个盘的柱号 |3 mcL'
int TotalMoves = (1 << height) - 1; VS3lz?o?6g
for (i=1; i <= TotalMoves; i++) %7[q%S
{ rvuasr~
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 =q}Z2 OoYh
{ Rj3ad 3z'E
BitStr[j] = 0; KAgxIz!^-1
} |$g} &P8;
BitStr[j] = 1; *!pn6OJ"Q}
Disk = j+1; De2$:?
if (Disk == 1) ,P%i%YPj
{ hP}-yW6]
fromPole = Hold[0]; 5zOC zm
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 mt~E&Z(A
temp = fromPole; //保存上一次从哪个柱子移动过来的 E24j(>
} i.{.koH<
else Rn)fwGC
{ OIDP#K
fromPole = Hold[Disk-1]; nNf*Q
r%Z
toPole = 6 - Hold[0] - Hold[Disk-1]; *7w!~mn[m
} aNBwb9X
cout << "Move disk " << Disk << " from " << Place[fromPole-1] B=~uJUr
<< " to " << Place[toPole-1] << endl; =b, m31
Hold[Disk-1] = toPole; 0g9y4z{H
} Xk!wT2;
} \-SC-c
%C_c%3d
kbo9nY1k
g
&?}A/(#
~C>clkZ
int main(int argc, char *argv[]) rv`GOta*
{ 1@i/N
cout << "Towers of Hanoi: " << endl Nt\0) &b
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; ^*w}+tB
cout << "Input the height of the original tower: "; "T*1C=
int height; sX-@
>%l
cin >> height; c
dWg_WBC
hanoi(height); r'4Dj&9Ac
Ww"]3
system("PAUSE"); qeb} ~FL"o
return EXIT_SUCCESS; C-\3,
} xIwILY|W=
O`5h jq#
+cM~|
h^
K]ASj
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 [N#4H3GM8
Km,%p@`m
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 q0DRT4K
[RY Rt/?Q
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 X` J86G )
P| hwLM
算法要点有二: mZG n:f}=
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 4;Vi@(G)
}1%%`
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 m41%?uC/
TV#>x!5!d
动的盘子编号有确定关系。 o/Q|R+yXV
%'X~9Pvi
2、这个盘子往哪个柱子上移。 r*dNta<
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 hiEYIx
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 mkhWbzD'S
#SG.`J<%
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 dS\!tdHP-Q
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 -2(?O`tZ
IMBjI#\
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。