下面是完整的模拟代码. 是完全的最笨的那种模拟. 任何递归都可以用这种模拟的办法
来完成转换. 当然, 在这种基本模拟的方式上, 有更好的做法, 就可以采用更聪明的办法.
//--------------------------------------------
#include <stdio.h>
#include <stack.h> // 自己实现一个吧...
// "返回地址"
typedef enum {
____RET_ADDR1,
____RET_ADDR2,
____RET_ADDR3
} ret_addr;
// 用来保存调用方的函数所有状态
struct data_t {
____char from;
____char pass;
____char to;
____int n;
____ret_ddr addr;
};
void set_data(struct data_t *data, char from, char pass, char to, int n, int addr)
{
____data->from = from, data->pass = pass, data->to = to, data->n = n,
____data->addr = addr;
}
void hanoi(char from, char pass, char to, int n)
{
____// 创建一个栈, 每个栈上元素的大小为 sizeof(struct data_t)
____stack_t *st = stack_create(sizeof(struct data_t), NULL);
____struct data_t data;
____char tmp;
// start 就是函数的开始咯.
start:
____if (n == 1) {
________printf("%c ==> %c\n", from, to);
____} else {
________// 保存当前函数的状态(包括所有局部变量, 以及"返回地址")
________set_data(&data, from, pass, to, n, RET_ADDR1);
________stack_push(st, &data);
________// 然后给函数传递参数, 并"调用函数"
________// 这几个赋值就相当于传递参数, goto start 就是"调用函数"
________// ret_addr1 标签就是调用函数完了之后的"返回地址"
________// from = from;
________tmp = pass, pass = to, to = tmp, n = n - 1;
________goto start;
ret_addr1:
________// 同上...
________set_data(&data, from, pass, to, n, RET_ADDR2);
________stack_push(st, &data);
________// from = from, pass = pass, to = to;
________n = 1;
________goto start;
ret_addr2:
________// 同上...
________set_data(&data, from, pass, to, n, RET_ADDR3);
________stack_push(st, &data);
________// to = to;
________tmp = from, from = pass, pass = tmp, n = n - 1;
________goto start;
ret_addr3:
________; // 这里有个分号, C语言不允许标签后面没有语句, 所以用个空语句占位.
____}
// 这里就是原来的递归函数的 return 的地方. return 的时候就回到调用方咯
// 如果栈空了, goto exit 即退出.
____if (stack_isempty(st))
________goto exit;
// 弹栈, 弹出调用方的数据(就是说这里是被调用方执行完了, 要返回到调用方继续)
____stack_pop(st, &data);
// 恢复调用方的数据
____from = data.from, pass = data.pass, to = data.to, n = data.n;
// 调用方在哪里调的, 就返回到那个调用处的下面.
____switch (data.addr)
____{
________case RET_ADDR1:
____________goto ret_addr1;
________case RET_ADDR2:
____________goto ret_addr2;
________case RET_ADDR3:
____________goto ret_addr3;
____}
exit:
____// 销毁手工栈.
____stack_destroy(st);
}
int main(void)
{
____int n;
____printf("pls input n: ");
____scanf("%d", &n);
____hanoi('A', 'B', 'C', n);
____return 0;
}
好了. 以上的代码就是模拟的实例... 看懂这个, 别的递归灵活处理即可.