读书人

关于汉诺塔的有关问题利用栈来解决!

发布时间: 2012-04-10 21:03:56 作者: rapoo

关于汉诺塔的问题,利用栈来解决!求源代码!
现在在研究数据结构!里面汉诺塔的问题很是费解啊!!要用栈来存储盘子的数目!!怎么做啊!还要比较吧!
希望高手能附上源代码c的!

[解决办法]

C/C++ code
一位美国学者发现一种出人意料的方法,只要轮流进行两步操作就可以了。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上。根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C;若n为奇数,按顺时针方向依次摆放 A C B。(1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。(2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘(这一步没有明确规定移动哪个圆盘,你可能以为会有多     种可能性,其实不然,可实施的行动是唯一的)。(3)反复进行(1)(2)操作,最后就能按规定完成汉诺塔的移动。程序设计思想:(1)将盘子标号为1,2,3......;   1 代表最小的盘子;     三根柱子分别为top[0]、top[1]、top[2]     将柱子标号为top[0]、top[1]、top[2]有利于盘子的顺序移动。用LowTray记录最小盘子(1号)所在柱子的标号。     1>、TrayAmount(盘子总数)为偶数时,将1号盘子由top[LowTray]移动到top[sub]     sub = (LowTray + 1) % 3     (TrayAmount(盘子总数)为奇数时,将1号盘子由top[LowTray]移动到top[sub]     sub = (LowTray + 2) % 3    )     2>、把另外两根柱子上可以移动的圆盘移动到新的柱子上。我将top[0]、top[1]、top[2]栈尾值设为65(top->tray = 65),这样可以通过比较两个栈顶元的大小来决定移动哪一个盘子      (移动较小的圆盘)。     3>、当top[0]、top[1]上没有盘子时停止(2)输出格式:Move tray 1 : 0-->2     表示将盘子 1 从top[0]移动到top[2]/**hanoi塔问题;用非递归实现 *将盘子标号为1,2,3......;   1 代表最小的盘子;*三根柱子分别为top[0]、top[1]、top[2]*/#include<stdio.h>#include<malloc.h>typedef int ElemType;typedef struct stack{    ElemType tray;    struct stack *next;}stack;stack *top[3];/**功能:建立空栈*返回:栈顶指针*/stack *CreateStack(){    stack *top;    top = (stack *)malloc(sizeof (stack));    top->tray = 65;    top->next = NULL;    return(top);}/**功能:进栈*参数:进栈无素,栈顶指针*返回:栈顶指针*/stack *push(int e, stack *top){    stack *p;    p = top;    top = (stack *)malloc(sizeof (stack));    top->next = p;    top->tray = e;    return(top);}/**功能:出栈*参数:栈顶指针*返回:栈顶指针*/stack *pop(stack *top){    stack *p;    p = top;    top = top->next;    free(p);    return(top);}/**功能:移动盘子并输出移动路径*参数:盘子总数*/void hanoi(int TrayAmount){    int sub, n, i, LowTray = 0;//LowTray是最小盘子(1号)所在柱子的标号    n = TrayAmount % 2;//TrayAmount为偶数时n = 0;TrayAmount为奇数时n = 1    while (!(top[0]->tray == 65 && top[1]->tray == 65))//当top[0]、top[1]上没有盘子时停止    {        i = LowTray;        sub = i + 1 + n;        sub = sub % 3;        top[sub] = push(top[i]->tray, top[sub]);//移动1号盘        top[i] = pop(top[i]);        printf("Move tray 1 :%d-->%d\n", i, sub);        sub = i + 2 - n;        sub = sub % 3;        if (top[i]->tray < top[sub]->tray)        {            top[sub] = push(top[i]->tray, top[sub]);            printf("Move tray %d :%d-->%d\n",top[i]->tray, i, sub);            top[i] = pop(top[i]);        }        else if (top[i]->tray > top[sub]->tray)        {            top[i] = push(top[sub]->tray, top[i]);            printf("Move tray %d :%d-->%d\n", top[i]->tray, sub, i);            top[sub] = pop(top[sub]);        }        LowTray = LowTray + n + 1;        LowTray = LowTray % 3;    }}void main(){    int i = 0, TrayAmount;    top[0] = CreateStack();    top[1] = CreateStack();    top[2] = CreateStack();    printf("Enter TrayAmount:\nTrayAmount=");    scanf("%d", &TrayAmount);//TrayAmount盘子总数;    for (i = TrayAmount; i > 0; i-- )//盘子都放在柱子0上    {        top[0] = push(i, top[0]);    }        hanoi(TrayAmount);} 

读书人网 >C语言

热点推荐