hanoi的使用递归和使用栈来解决
2020-07-20 04:11
204 查看
hanoi塔问题
hanoi塔问题就是讲该问题的主要材料包括三根高度相同的柱子和一些大小及颜色不同的圆盘,三根柱子分别为起始柱x、辅助柱y及目标柱z,将所有圆盘从x移到z,一次移动一个,而且不允许大的圆盘压在小的上面,会压碎,可以使用y盘进行辅助。
递归
很简短的几行代码
始终把x上所有圆盘看做两块
- 一块是最下面的一块
- 一块是最下面一块上面所有的
把三个柱子设为x,y,z,一开始都在x上面。
两块的hanoi就是直接将上面的一块移到y,下面的一块移到z,最后将y移到z
至于为何是
hanoi(n-1,x,z,y); cout<<n<<"个"<<x<<"-->"<<z<<endl; hanoi(n-1,y,x,z);
可以看到只有中间当移动一块时是直接输出的,移动多块时是表示x借助y移到z上,因为上面是多块不是一块,不能直接移动,要借助一个空的柱子。可以借助三块的例子来向一下。
当把上面两块当成一个整体来移动,必须借助一个空的将最小的一块安置一下才能实现两块一起动。
#include<iostream> using namespace std; void hanoi(int n,char x,char y,char z) { if(n==1) { cout<<1<<"个"<<x<<"-->"<<z<<endl; } else { hanoi(n-1,x,z,y); cout<<n<<"个"<<x<<"-->"<<z<<endl; hanoi(n-1,y,x,z); } } int main() { int n; cin>>n; hanoi(n,'x','y','z'); }
不用递归
- 任何尾递归都可以用循环来替代。
- 不是尾递归可以使用数据结构中的栈来替代。
-尾递归的含义
每一个函数在使用时就相当于进栈,当return时就出栈。
所以递归就是不断入栈,当到出口时就逐一出栈,所以递归实际上总是从出口开始执行,出口在栈顶。
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct record //就像用递归里面的三个变量 { int n; char x; char y; char z; struct record *next; } record; typedef struct stack //定义一个栈 { record * records; int num; } stack; void push(record *record, stack *stack) //向栈内放置元素 { stack->num++; record->next = stack->records; stack->records = record; } bool pop(stack *stack,record *&e) //从栈顶弹出元素 { if(stack->num==-1) return false; stack->num--; e = stack->records; stack->records = stack->records->next; return true; } void move(int n, char x, char y, char z) { stack stack = { NULL, 0 }; record *record1, *p_record; //初始化栈 record1 = (record *)malloc(sizeof(record)); record1->n = n, record1->x = x, record1->z = z; record1->y = y; push(record1, &stack); //迭代开始 while (stack.num != 0) { //取出一个元素,进行一下操作,把他相当于两块,和用递归一样。 pop(&stack,p_record); if (p_record->n == 1)//这里表示当只有一块时直接输出就行了。 { printf("%c->%c\t", p_record->x, p_record->z); free(p_record); continue; } //记录递归环境,并放入栈中 record *record2 = (record *)malloc(sizeof(record)); record *record3 = (record *)malloc(sizeof(record)); record *record4 = (record *)malloc(sizeof(record)); record2->n = p_record->n - 1, record2->x = p_record->x, record2->z = p_record->y, record2->y = p_record->z; record3->n = 1, record3->x = p_record->x, record3->z = p_record->z, record3->y = p_record->y;//n=1就可以直接移动,也就是直接输出 record4->n = p_record->n - 1, record4->x = p_record->y, record4->z = p_record->z, record4->y = p_record->x; //出栈一个进栈三个 push(record4, &stack); push(record3, &stack); push(record2, &stack); //释放内存 free(p_record); } } int main() { int n; scanf("%d",&n); //调用move方法 move(n, 'A', 'B', 'C'); return 0; }
相关文章推荐
- 使用函数的递归调用来解决Hanoi(汉诺)塔问题。
- SQL Server 2005新特性之使用with关键字解决递归父子关系
- 数据结构的应用——使用栈和递归实现Hanoi问题求解
- SQL Server 2005新特性之使用with关键字解决递归父子关系
- c语言使用递归思想解决扩散问题实例
- 用C语言解决(hanoi)汉诺塔问题——函数的递归调用
- 何时使用递归解决问题?-重建二叉树
- SQL Server 2005新特性之使用with关键字解决递归父子关系
- 使用递归解决一种约瑟夫问题
- 递归解决 Tower of Hanoi 问题
- 使用Python来解决卡诺塔即递归问题
- SQL Server 2005---使用with关键字解决递归父子关系
- 使用递归解决问题的一般思路
- python使用递归解决全排列数字示例
- getDatabase called recursively数据库递归使用错误---解决方法
- 一道数列的规律题(使用递归解决)
- 使用递归-分治方法解决汉诺塔问题
- 算法——使用递归解决组合问题
- SQL Server 2005新特性之使用with关键字解决递归父子关系
- 使用递推和递归解决斐波那契数列问题~~~