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

汉诺塔非递归算法

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
汉诺塔非递归算法.我只是将盘子的数量等于2,3的情况代到网上别人给的算法中验证了一下,没有错。并没有证明算法的正确性。算法是否有效,有待大家证明。 sN[<{;K4  
l0!`>Xx[b  
include <iostream> !9C]Fs*`?  
#include <stdlib.h> 4}Os>M{k  
>4lA+1JYk  
#ifdef _WIN32 ] C_$zbmi  
using namespace std; /#x0?d {5  
#endif ;cv\v(0  
^7kYG7/  
static void hanoi(int height) OJ\j6owA  
{ D#ED?Lqf  
  int fromPole, toPole, Disk; PVq y\i  
  int *BitStr = new int[height],   //用来计算移动的盘的号码 pkIJbI{aS  
    *Hold   = new int[height];   //用来存贮当前的盘的位置。hold[0]为第一个盘所在的柱号 g>?,,y6/w  
  char Place[] = {'A', 'C', 'B'}; &fxyY (  
  int i, j, temp; sBN4:8  
B`%%,SLJ  
  for (i=0; i < height; i++)               oe_,q&e  
  { NUY sQO)  
    BitStr = 0; I7#+B1t  
    Hold = 1; gepYV}  
  } >y@3`u]  
  temp = 3 - (height % 2);               //第一个盘的柱号 2c9]Ja3:6  
  int TotalMoves = (1 << height) - 1; q={3fm  
  for (i=1; i <= TotalMoves; i++) x5yZ+`Gc  
  { (j)>npOd9  
    for (j=0 ; BitStr[j] != 0; j++)         //计算要移动的盘 P^/e!%UgC  
    { w\a9A#v,  
        BitStr[j] = 0; FbPoyh  
    } t-hN4WKH_A  
    BitStr[j] = 1; !\Q/~p'jS  
    Disk = j+1; Y,%G5X@S<  
    if (Disk == 1) W<H^V"^  
    { ra\2BS)X  
        fromPole = Hold[0]; &2Cu"O'.i  
        toPole = 6 - fromPole - temp; //1+2+3等于6,所以6减去其它两个,剩下那个就是要移去的柱子 JR/^Go$^  
        temp = fromPole;     //保存上一次从哪个柱子移动过来的 4mWT"T-8  
    } q'[yYPDX5x  
    else K@=_&A!  
    { 5r\Rfma  
        fromPole = Hold[Disk-1]; \xtmd[7lb<  
        toPole = 6 - Hold[0] - Hold[Disk-1]; j98>Jr\  
    }     J@9E20$  
    cout << "Move disk " << Disk << " from " << Place[fromPole-1] <Y#EiC.  
        << " to " << Place[toPole-1] << endl; /I#SP/M&l  
    Hold[Disk-1] = toPole; %$(*.o!+8  
  } }15ooe%  
} k@C]~1  
gl6*bB=  
Y4/ !b  
jDM^e4U.l  
<+7-^o _  
int main(int argc, char *argv[]) | )R{(AK-  
{ DO=zxdTI!  
  cout << "Towers of Hanoi: " << endl Gm LKg >%  
      << "moving a tower of n disks from pole A to pole B by using pole C" << endl; WXE{uGc  
  cout << "Input the height of the original tower: "; DvXbbhp  
  int height; Zh.9j7 >p  
  cin >> height; x42m+5/  
  hanoi(height); .SSj=q4?  
@y\M8C8  
  system("PAUSE"); @7B!(Q  
  return EXIT_SUCCESS; .zyi'Kj  
} wkZ}o,{*:  
8:0.Pi(ln@  
!Zf)N_k  
,ffH:3F  
问题描述:有三个柱子A, B, C. A柱子上叠放有n个盘子,每个盘子都比它下面的盘子要小一点,可以从上 KbF,jm5  
9/S-=VOe.t  
到下用1, 2, ..., n编号。要求借助柱子C,把柱子A上的所有的盘子移动到柱子B上。移动条件为:1、一 U_c9T>=  
ur`:wR] 2?  
次只能移一个盘子;2、移动过程中大盘子不能放在小盘子上,只能小盘子放在大盘子上。 X5D}<J2"  
H`ZUI8-  
算法要点有二: fNaS?tV)  
1、确定哪一个盘子要移动。有n个盘子的Hanoi塔需要移动2^n -1次,设m为n位的二进制数,则m的取值范 Q2/ZO2  
E%C02sI  
围为0~2^n -1。让m每次递增1,可以发现,m中最低一位的刚刚由0变为1的位置的位置编号,和即将要移 zpd Z.  
}Pe0zx.Ge  
动的盘子编号有确定关系。 l< RztzUw  
(f|3(u'e?  
2、这个盘子往哪个柱子上移。 pVm'XP  
a.第一次需要移动1号盘,n为奇数时,1号盘首先移动到柱子B,为偶数时首先移动到柱子C。 GKKf#r74  
b.接下来如果移动的盘子不是1号盘。你有两个柱子可以选择。先找到1号盘所在的柱子,因为移动的盘子 ^cF_z}Zi+  
=h 2zIcj  
不能叠放到1号盘上,所以该盘可以移动的位置就是没有1号盘的那个柱子。 vSy#[9}  
c.如果移动的盘子是1号盘。也有两个柱子可以选择。找到1号盘原先是从哪个柱子上移来的,因为移动的 B?J #NFUb  
y"SVZ} ;|  
顺序(顺时针或逆时针)一旦确定,就不会更改,所以排除from的那个柱子后,移动方向也就唯一了。
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
描述
快速回复

您目前还是游客,请 登录注册
批量上传需要先选择文件,再选择上传
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八