用栈实现汉诺塔

来源:互联网 发布:flash ftp软件绿色版 编辑:程序博客网 时间:2024/06/06 03:26

汉诺(Hanoi)塔问题

又称为河内塔问题。有位僧人整天把三根柱子上的金盘倒来倒去,原来他是想把64个一个比一个小的金盘从一根柱子上移到另一根柱子上去。移动过程中遵守以下规则:每次只允许移动一只盘,且大盘不得落在小盘上。如下图所示:

在如何编写递归程序(分治法)中,利用分治法递归程序提出了汉诺塔实现的方法,但是并没有在程序中真正地实现 。由于汉诺塔的规则与栈的规则类似(先入后出),因此提出了用栈具体实现汉诺塔。

在栈的链式实现(C语言)中实现了栈的相关操作,在此不作讲解,只列出需要用到的操作函数。

实现代码:

typedef struct node //栈的结点结构{int data;struct node *next;}*Link;typedef struct{ //栈顶作链表的头部Link top;}*Stack;Stack init_stack(); // 定义栈int push_stack(Stack s,int x); // 变量x入栈int pop_stack(Stack s,int &x); // 出栈顶元素到xint pop_push(Stack sa,Stack sb); //栈sa出栈一次,数据入栈到sbvoid hanoi(int n,Stack sa,Stack sb,Stack sc) //把sa栈顶的n个元素按顺序放到栈sc中void main(){int n;scanf("%d", &n); // 汉诺塔的层数Stack sa = init_stack();Stack sb = init_stack();Stack sc = init_stack();while(n-->0) // 初始化栈sa,代表最左边柱子和盘子{ push_stack(sa,i); }hanoi(n,sa,sb,sc); }void hanoi(int n,Stack sa,Stack sb,Stack sc){if(n == 1) // 盘子数为1pop_push(sa,sc);else{hanoi(n-1,sa,sc,sb); // 将栈sa的n-1个盘子顺序移到栈sbpop_push(sa,sc); // 将栈sa的第n个盘子移到栈schanoi(n-1,sb,sc,sa); // 将栈sb的n-1个盘子顺序移到栈sc}}int pop_push(Stack sa,Stack sb){int x;if(sa->top ==NULL){printf("栈空");return 0;}else{pop_stack(sa,x); // 栈sa出栈push_stack(sb,x); // 栈sb入栈return 1;}}

栈sa首先被初始化,反序装入n~1的数字,代表盘子的大小顺序,程序运行后,栈sa元素都移到栈sc中,且顺序与sa初始化后顺序相同,因此从数据层面上实现了汉诺塔。由于实现汉诺塔需要的移动次数非常大,因此在输入汉诺塔层数时,尽量不要输入比较大的数,以免程序运行时间过长。

1 0
原创粉丝点击