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

汉诺塔非递归算法

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 !A-;NGxE  
EVz9WY  
include <iostream> S:97B\ u`  
#include <stdlib.h> ]Y5dl;xrM)  
;/A}}B]y  
#ifdef _WIN32 u8uW9 <  
using namespace std; Q;gQfr"c7  
#endif 5ZsDgOeY  
Sr7@buF  
static void hanoi(int height) m!!;/e?yx  
{ @,6ST0xT (  
  int fromPole, toPole, Disk; &wGg6$  
  int *BitStr = new int[height],   //用来计算移动的盘的号码 rt;gC[3\  
    *Hold   = new int[height];   //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 vl~%o@*_  
  char Place[] = {'A', 'C', 'B'}; 'wE\{1~_[+  
  int i, j, temp; @^HwrwRA  
KZ\dB;W< |  
  for (i=0; i < height; i++)               _W+Q3Jx-(  
  { $~o3}&az  
    BitStr = 0; ^Ezcy?  
    Hold = 1; R<j<. h  
  } N l|^o{#  
  temp = 3 - (height % 2);               //第一个盘的柱号 MgP{W=h2  
  int TotalMoves = (1 << height) - 1; TAAR'Jz S  
  for (i=1; i <= TotalMoves; i++) >C^/,/%v  
  { 0# UAjT3  
    for (j=0 ; BitStr[j] != 0; j++)         //计算要移动的盘 P%jkKE?B4  
    { [Y oa"K  
        BitStr[j] = 0; Ltg-w\?]  
    } 7 s-`QdWX  
    BitStr[j] = 1; y[p6y[r*  
    Disk = j+1; Bfn]-]>sD  
    if (Disk == 1) CRd_}  
    { -&7=uRQk  
        fromPole = Hold[0]; e@+v9Bs]q  
        toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 Ei~]iZ}  
        temp = fromPole;     //保存上一次从哪个柱子移动过来的 yUj;4vd  
    } o3= .T+B  
    else '}fel5YV  
    { 5Q;dnC  
        fromPole = Hold[Disk-1]; [wIKK/O  
        toPole = 6 - Hold[0] - Hold[Disk-1]; -g$O OJB6  
    }     _X?y ,#  
    cout << "Move disk " << Disk << " from " << Place[fromPole-1] z=%IcSx;  
        << " to " << Place[toPole-1] << endl; &08 Tns"  
    Hold[Disk-1] = toPole; `x< 0A  
  } (V^QQ !:  
} [BE:+ ID3  
)_F(H)*  
X%35XC.n  
& ]%\.m  
c}8 -/P=  
int main(int argc, char *argv[]) _we3jzMW  
{ B*BHF95!  
  cout << "Towers of Hanoi: " << endl 'iGMn_&  
      << "moving a tower of n disks from pole A to pole B by using pole C" << endl; W=M< c@  
  cout << "Input the height of the original tower: "; >]C<j4  
  int height; FcY$k%;'Q  
  cin >> height; l [x%I  
  hanoi(height); &LwJ'h +nd  
iPNd!_  
  system("PAUSE"); L c{!FG>  
  return EXIT_SUCCESS; zo87^y5?G  
} 'H FwP\HX  
Hc"N& %X[  
JH-nvv  
krwf8!bI  
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 )*+u\x_Hx  
Jn60i6/  
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 wo$|~ Hr  
(kdC1,E  
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 ]&/0  
CARq^xI-  
算法要点有二: i{4'cdr?  
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 '%3u%;"  
?F!W#   
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 /S/tE  
!+%Az*ik  
动的盘子编号有确定关系。 MQjG<O\  
EOofa6f&l  
2、这个盘子往哪个柱子上移。 +6wx58.B&  
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 TR+Q4Y:  
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 /1H9z`qV  
rn[$x(G  
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 ,WzG.3^m  
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 `s#sE.=o  
]9dx3<2_I  
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

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