汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 R rxRa[{Z
/LSq%~UF
include <iostream> :nt}7Dn'
#include <stdlib.h> Od*v5qT;$
EJv! tyJ\[
#ifdef _WIN32 $=7H1 w
using namespace std; ZIDFF
#endif x}uwWfe 3
%odw+PhO
static void hanoi(int height) YdPlN];[
{ KqFmFcf|
int fromPole, toPole, Disk; B>R*
f C@g
int *BitStr = new int[height], //用来计算移动的盘的号码 Cx$9#3\
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 J&(
char Place[] = {'A', 'C', 'B'}; Qb@BV&^y&
int i, j, temp; F=:F>6`
byp.V_a}/
for (i=0; i < height; i++) hcj{%^p
{ b$IY2W<Ln
BitStr = 0; $&bU2 ]
Hold = 1; UzXDi#Ky
} M_yZR^;^-
temp = 3 - (height % 2); //第一个盘的柱号 N45s'rF
int TotalMoves = (1 << height) - 1; KwY`<t1lA;
for (i=1; i <= TotalMoves; i++) AX/=}G
{ q=T<^Tk#e
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 rHH#@Zx
{ (M4]#5
BitStr[j] = 0; Z?5,cI[6#
} 1OuSH+
BitStr[j] = 1; "#[o?_GaJ
Disk = j+1; ER0TY,
if (Disk == 1) Z#H@BWN7
{ E>o&GYc
fromPole = Hold[0]; IO?~b X P
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 %w;1*~bH
temp = fromPole; //保存上一次从哪个柱子移动过来的 *C,$W\6sz
} K+(m'3`
else g`y/_
{ D7 8)4>X
fromPole = Hold[Disk-1]; !H2C9l:rd
toPole = 6 - Hold[0] - Hold[Disk-1]; ,Gf+U7'K
} bvt-leA=
cout << "Move disk " << Disk << " from " << Place[fromPole-1] Ke'YM{
<< " to " << Place[toPole-1] << endl; `K1PGibV
Hold[Disk-1] = toPole; cx,u2~43A&
} 1aXIhk4
} -Hl\j(D7
LWp?U!N
oZ|{J
:Map,]]B_
/jn:e"0~
int main(int argc, char *argv[]) zwF7DnW<<
{ cHfK-R
cout << "Towers of Hanoi: " << endl 4kN:=g
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; D(W7O>5vQ2
cout << "Input the height of the original tower: "; >QbI)if`1
int height; lBYS>4~
cin >> height; k;9#4^4(
hanoi(height); J{v6DYhi
@)FXG~C*
system("PAUSE"); iyHp$~,q?t
return EXIT_SUCCESS; [NR0] #h
} mAtG&my)
'JXN*YO
W"DxIy
zjhR9
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 *HfW(C$
v:!7n
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 ,&
{5,=
QyBK*uNdV
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 c9F[pfi(
ce-m)o/
算法要点有二: q,19NZ
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 R _~m\P
aF_ZV bS
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 ^~hhdwu3a
}@t'rK[
动的盘子编号有确定关系。 _*-'yu8#
%d~9at6-B
2、这个盘子往哪个柱子上移。 5<>R dLo
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 Xj&~N;Ysb
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 TPmZ/c^
&bRxy`ZH
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 0Ci"tA3"
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 WG!;,~f>o
~dX@5+Gd
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。