汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 d/Fjs0pt
:3{@LOil^
include <iostream> $fuFx8`2W
#include <stdlib.h> 1wqCoDgkp
fy9{W @E3p
#ifdef _WIN32 *sB=Ys?
using namespace std; qV8;;&8r
#endif eJ$?T7aUf
z15(8Y@2]
static void hanoi(int height) $9Y2\'w<h6
{ Hfm4
int fromPole, toPole, Disk; +z;xl-*[
int *BitStr = new int[height], //用来计算移动的盘的号码 +6uun
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 r/:s2oQ
char Place[] = {'A', 'C', 'B'}; [$9 sr=3:
int i, j, temp; m->
chOu~|
:h*20iP
for (i=0; i < height; i++) -5kq9Dy\,
{ sVaWg?=qs'
BitStr = 0; <`*6;j.&
Hold = 1; u =#LY$
}
(= uwx#
temp = 3 - (height % 2); //第一个盘的柱号 ?GB($D=Y'&
int TotalMoves = (1 << height) - 1; cV)fe`Gg
for (i=1; i <= TotalMoves; i++) ,t61IU3"
{ ]Fl+^aLS
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 1:q55!b
{ !z58,hv
BitStr[j] = 0; !0 *=z~
} =EsKFt"
BitStr[j] = 1; u|BD%5+J
Disk = j+1; aSXoYG0\
if (Disk == 1) w*#TS8
\
{ 76$19
fromPole = Hold[0]; R b\=\
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 (.
1<.PZp)
temp = fromPole; //保存上一次从哪个柱子移动过来的 .l !:|Fd
} D\N-ye1LE
else +*!oZKm.
{ H&3VPag
fromPole = Hold[Disk-1]; _Vj O
[hx
toPole = 6 - Hold[0] - Hold[Disk-1]; :[|`&_D9J
} ^?&Jq_oU
cout << "Move disk " << Disk << " from " << Place[fromPole-1] :]=Y1*L\)
<< " to " << Place[toPole-1] << endl; )|uPCZdLZ
Hold[Disk-1] = toPole; qJ#?=ITE
} c<DsCzX
} +lO
Y
IQ
\qV5mD]"M
>xJt&jW-
{B?%r[nW
H :d{Sru
int main(int argc, char *argv[]) `
n@[=l~
{ ' OdZ[AN
cout << "Towers of Hanoi: " << endl mL18FR N
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; 7<|1 xOT
cout << "Input the height of the original tower: "; A$Es(<'9g
int height; V4/P
cin >> height; v?fB:[dG
hanoi(height); Y@M=6G
REQ2pfk0
system("PAUSE"); Ml+.\'r
return EXIT_SUCCESS; .y+>-[j?B
} MvL%*("4b
m\"M`o
B
r7JILk
7ABHgw~?8r
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 V\!FD5%
p^5B_r:
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 xm/v:hl=
}@SZ!-t%rD
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 ~k|~Q\
dH#S69>
算法要点有二: =qCVy:RL4
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 (U/ 6~r'.L
;9=9D{-4+
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 )&se/x+
c^A3|tCi
动的盘子编号有确定关系。 iWGgt]RJ
4kxy7]W
2、这个盘子往哪个柱子上移。 :NA cad
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 <kPU*P,
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 C.%iQx`
W(~G^Xu
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 tojJQ6;J
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 Z9~~vf#
E
I)Pfx"0
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。