汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 o<N nV
eut-U/3: #
include <iostream> tg{H9tU;
#include <stdlib.h>
)oyIe)
*8LMn
#ifdef _WIN32 7}X[
4("bB
using namespace std; xD6@Qk
#endif Rz.? i+
() j=5KDu
static void hanoi(int height) B>2tZZko
{ >uSy
int fromPole, toPole, Disk; %mZ {4<7
int *BitStr = new int[height], //用来计算移动的盘的号码 M%@ !cW
*Hold = new int[height]; //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 p`l0?^r
c"
char Place[] = {'A', 'C', 'B'}; o_'p3nD
int i, j, temp; ]w.;4`l*
78/Zk}I]
for (i=0; i < height; i++) [D!jv"
{ ~c&bH]cj
BitStr = 0; bFW =ylF9
Hold = 1; @7B$Yy#
} .C--gQpIv
temp = 3 - (height % 2); //第一个盘的柱号 (;q;E\Ejq
int TotalMoves = (1 << height) - 1; rYbpih=x
for (i=1; i <= TotalMoves; i++) ({q?d[q[
{
6q{HU]N+
for (j=0 ; BitStr[j] != 0; j++) //计算要移动的盘 6Udov pl
{ B&@?*^.
BitStr[j] = 0; oZAB _A)[-
} <TP=oq?I/
BitStr[j] = 1; l6d$V9A
Disk = j+1; wYmM"60
if (Disk == 1) L|,!?cSAT
{ ;UfCj5`Q)4
fromPole = Hold[0]; Z-l=\ekJ
toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 8|" XSN
temp = fromPole; //保存上一次从哪个柱子移动过来的 ;A*`e$
} %T~ig[GstX
else v&=gF/$
{ o|$AyS{1
fromPole = Hold[Disk-1]; @~%r5pz6
toPole = 6 - Hold[0] - Hold[Disk-1]; kOed ]>H
} "T|PS6R~
cout << "Move disk " << Disk << " from " << Place[fromPole-1] A -b
[>}_
<< " to " << Place[toPole-1] << endl; QDhOhGK
Hold[Disk-1] = toPole; JhLgCnm
} AT%u%cE-
} ' hs2RSq
o}$EG
2* 2wY =
}yz (xH
*3?'4"B{8
int main(int argc, char *argv[]) Dp':oJC
{ 2n|K5FR()
cout << "Towers of Hanoi: " << endl 3J5!oF{H
<< "moving a tower of n disks from pole A to pole B by using pole C" << endl; 'JRvP!]
cout << "Input the height of the original tower: "; `tn{ei
int height; D8xmE2%
cin >> height; hK_LEwd;
hanoi(height); <?@NRFTe
3h *!V6%q
system("PAUSE"); F 9@h|#an
return EXIT_SUCCESS; sn)3ZA
} 6=fSE=]DY
{$wjO7Glp
D`$hPYK|_
0`[wpZ
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 m5r7
lQe%Yh
>rl
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 sL\L"rQN6
[_}J F}6
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 fIsp;ca[k
#n#@fAY
算法要点有二: /|D*w^>
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 tQBRA/
, T8>}U(
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 6e[VgN-s
{\:{[{qF
动的盘子编号有确定关系。 D>LZP!
5Er2}KZJv,
2、这个盘子往哪个柱子上移。 *^:N.&]
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 \Z+z?K O
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 #3+!ee27#
TL}++e
7+
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 '7iSp=
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 )3>hhuaa
{qN 5MsY
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。