关于汉诺塔的有关问题,利用栈来解决!求源代码
关于汉诺塔的问题,利用栈来解决!求源代码!
现在在研究数据结构!里面汉诺塔的问题很是费解啊!!要用栈来存储盘子的数目!!怎么做啊!还要比较吧!
希望高手能附上源代码c的!
------解决方案--------------------
现在在研究数据结构!里面汉诺塔的问题很是费解啊!!要用栈来存储盘子的数目!!怎么做啊!还要比较吧!
希望高手能附上源代码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); }