社区应用 最新帖子 精华区 社区服务 会员列表 统计排行 社区论坛任务 迷你宠物
  • 3405阅读
  • 0回复

汉诺塔非递归算法

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 oVl:./(IB  
D-ug$ZRg  
include <iostream>  V}8J&(\  
#include <stdlib.h> S`0@fieOf  
He#+zE ;  
#ifdef _WIN32 Oq+C<}eg  
using namespace std; O;H/15j:sK  
#endif M_9|YjwS  
fD,#z&  
static void hanoi(int height) {y<_S]0  
{ EVb'x Zr  
  int fromPole, toPole, Disk; #\`6ZHW  
  int *BitStr = new int[height],   //用来计算移动的盘的号码 d:A+s>`$M  
    *Hold   = new int[height];   //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 Jb ;el*,K  
  char Place[] = {'A', 'C', 'B'}; H7l[5 ib  
  int i, j, temp; 4RTEXoXs  
!29 Rl`9  
  for (i=0; i < height; i++)               (B$2)yZY  
  { 'J!P:.=a>  
    BitStr = 0;  U,Z(h  
    Hold = 1; 5fVdtJk7  
  } <6(u%t0k5  
  temp = 3 - (height % 2);               //第一个盘的柱号 s?0r\cc|:  
  int TotalMoves = (1 << height) - 1; 2a? d:21 B  
  for (i=1; i <= TotalMoves; i++) dr9I+c7u  
  { )}paQmy#  
    for (j=0 ; BitStr[j] != 0; j++)         //计算要移动的盘 3*8#cSQ/6o  
    { i&_sbQ^  
        BitStr[j] = 0; nH[@EL  
    } YjHGdacs  
    BitStr[j] = 1; o &Nr5S  
    Disk = j+1; hfEGkaV._3  
    if (Disk == 1) :Ur%.0  
    { 4=q\CK2^A  
        fromPole = Hold[0]; ^]aDLjD  
        toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 iT.hXzPzr*  
        temp = fromPole;     //保存上一次从哪个柱子移动过来的 ](T*f'LN  
    } ss,6;wfX  
    else &<!I]:Y  
    { #}k^g:l1  
        fromPole = Hold[Disk-1]; ;| \Ojuf  
        toPole = 6 - Hold[0] - Hold[Disk-1]; hTg%T#m  
    }     E"u>&uPH  
    cout << "Move disk " << Disk << " from " << Place[fromPole-1] n'M}6XUw  
        << " to " << Place[toPole-1] << endl; i(U*<1y  
    Hold[Disk-1] = toPole; z&-3H/   
  } @8/-^Rh*  
}  Y9PG  
RQe#X6'h  
8.9S91]=  
.^Ek1fi.  
rJ<v1Yb  
int main(int argc, char *argv[]) CZbp}:|  
{ IClnh1=  
  cout << "Towers of Hanoi: " << endl W6wgX0H  
      << "moving a tower of n disks from pole A to pole B by using pole C" << endl; ;itz` 9T  
  cout << "Input the height of the original tower: "; [kC-g @  
  int height; fmloh1{4  
  cin >> height; u1>|2D  
  hanoi(height); %Xp}d5-  
Jh }3AoD  
  system("PAUSE"); (( t8  
  return EXIT_SUCCESS; ^Z}INUv]7  
} ~BZA_w"`1  
[qid4S~r,&  
wAy;ZNu  
3YRhqp"E  
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 #M8"b]oh6  
)8e_<^M  
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 v?Y9z!M  
2Uk$9s  
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 0~^opNR  
(^057  
算法要点有二: 5N ' QG<jE  
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 (u$Q  
3:);vh!  
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 =DF7l<&km  
N5oao'7|A  
动的盘子编号有确定关系。 #ljfcQm  
@gs Kb* ,  
2、这个盘子往哪个柱子上移。 +hK Qha!*  
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 YMJjO0  
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 *S{%+1F  
kS+*@o  
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 ^$yr-p%-  
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 ,D~C40f  
# {!Qf\1M  
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录注册
温馨提示:欢迎交流讨论,请勿纯表情、纯引用!
认证码:
验证问题:
10+5=?,请输入中文答案:十五