汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 kC=e>v
byj}36LN62
include <iostream> JGP<'6"L$
#include <stdlib.h> NVEjUt/
+-~:E_G
#ifdef _WIN32 WaU+ZgDrG
using namespace std; #WBlEVx;Z
#endif _JlbVe[<
taS2b#6\+
static void hanoi(int height) 'A0.(a5
{ k4|9'V&1*6
int fromPole, toPole, Disk; Dc,h(2
int *BitStr = new int[height], //用来计算移动的盘的号码 6mP
s;I
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 kB|jN~
char Place[] = {'A', 'C', 'B'}; a[<'%S#3x
int i, j, temp; XIM!]
(x}>tm
for (i=0; i < height; i++) L* k[Vc
{ sSisO?F!Z
BitStr = 0; q[6tvPfkX
Hold = 1; ,o$F~KPu
} e rz9CX
temp = 3 - (height % 2); //第一个盘的柱号 "<c^`#CWuO
int TotalMoves = (1 << height) - 1; W6.
)7Y,
for (i=1; i <= TotalMoves; i++) "}_b,5lkGK
{ 'z=WJV;Vs
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 T3HAr9i%)
{ ff.(X!
BitStr[j] = 0; T#;W5<"
} #) eI]
BitStr[j] = 1; Fai_v{&?
Disk = j+1; k
lLhi<*
if (Disk == 1) d|GQZAEJEt
{ (w31W[V'#
fromPole = Hold[0]; V3%"z
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 ~H[
temp = fromPole; //保存上一次从哪个柱子移动过来的 _ZM$&6EC
} 9FB[`}
else N=1zhI:VaQ
{ AJk0jh\.j%
fromPole = Hold[Disk-1]; ao4"=My*G
toPole = 6 - Hold[0] - Hold[Disk-1]; >s
4"2X
} U(lcQC`$
cout << "Move disk " << Disk << " from " << Place[fromPole-1] J~=bW\^I
<< " to " << Place[toPole-1] << endl; +_.k\CRms
Hold[Disk-1] = toPole; :}QBrd
} BCDmce`=l
} $XBn:0U
tUS)1*{_
]V|rOt xb
m5!~PG:_
^/nj2"
int main(int argc, char *argv[]) }ll&qb
{ W'aZw9
cout << "Towers of Hanoi: " << endl UKYQ @m
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; F32N e6Y6"
cout << "Input the height of the original tower: "; 8v$2*$
int height; XJx$HM&0M
cin >> height; $uw[X
hanoi(height); DtXQLL*fl(
$]V,H"
system("PAUSE"); PUt\^ke
return EXIT_SUCCESS; )?5027^
} #6t 4 vJ1
/ z<7gd~oU
eWKFs)C]
=mVWfFL
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 7_OC&hhL
^!Y]l
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 MQs!+Z"m>
d:Y!!LV-@L
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 T1$fu(f
nWfzwXP>_
算法要点有二: j@N z
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 bjn: e!}
W<f-
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 gN,O)@N'd3
3.i$lp`t
动的盘子编号有确定关系。 #?x!:i$-
Ck:RlF[6C
2、这个盘子往哪个柱子上移。 2TFb!?/RQ
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 #&V7CYJ
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 1NHiW
v
I5nxY)v
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 OyI?P_0u
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 ` ,lm:x+(0
YmrrZ&]q
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。