汉诺塔非递归算法C语言实现
m根柱子的汉诺塔问题 c++
![m根柱子的汉诺塔问题 c++](https://img.taocdn.com/s3/m/a603a34191c69ec3d5bbfd0a79563c1ec4dad753.png)
题目:C++中解决汉诺塔问题的方法一、引言汉诺塔问题是一个经典的数学问题,最早由法国数学家爱德华·卢卡斯在1883年发现并提出。
这个问题可以用来引出递归、分治等算法设计思想,也是程序设计中的经典问题之一。
本文将介绍如何使用C++语言来解决汉诺塔问题。
二、汉诺塔问题的描述汉诺塔问题的具体描述是:有三根柱子,标记为A、B、C,A柱子上有N个不同大小的圆盘,较大的圆盘必须始终位于较小的圆盘上。
要求将A柱子上的圆盘全部移动到C柱子上,并且在移动过程中始终保持较大的圆盘在下面,较小的圆盘在上面。
三、递归解法递归是解决汉诺塔问题的一种常用方法。
具体的解法可以描述为:1. 如果只有一个圆盘,直接将其从A柱子移动到C柱子即可;2. 如果有N个圆盘,那么可以将其分解为两个子问题:首先将N-1个圆盘从A柱子移动到B柱子,然后将最大的圆盘从A柱子移动到C柱子,最后将N-1个圆盘从B柱子移动到C柱子。
四、C++代码实现下面是使用C++语言实现汉诺塔问题的递归解法的代码示例:```cpp#include <iostream>using namespace std;void hanoi(int n, char from, char to, char aux) {if (n == 1) {cout << "Move disk 1 from " << from << " to " << to << endl;return;}hanoi(n - 1, from, aux, to);cout << "Move disk " << n << " from " << from << " to " << to << endl;hanoi(n - 1, aux, to, from);}int main() {int num_disks;cout << "Enter the number of disks: ";cin >> num_disks;hanoi(num_disks, 'A', 'C', 'B');return 0;```在这段代码中,hanoi函数是递归解决汉诺塔问题的核心代码。
汉诺塔问题的非递归算法设计及可视化实现
![汉诺塔问题的非递归算法设计及可视化实现](https://img.taocdn.com/s3/m/68117158ff4733687e21af45b307e87101f6f877.png)
汉诺塔问题的非递归算法设计及可视化实现彭伟【摘要】This essay introduces the classic recursive algorithm of the famous Hanoi,and then carries out further analysis and study on the algorithm based on the binary recursive tree to get a non-recursive solution without using the stack technology.Finally,designing procedures of development environment are visualized in NET,using recursive and non-recursive algorithm respectively to solve Hanoi of specified scale,with the moving effects of disc being dynamically simulated.%讨论了汉诺塔问题的经典递归算法,并基于二叉递归树对算法进行研究,得出了一种不使用堆栈技术的非递归解法,最后在.NET可视化开发环境下设计程序,分别用递归与非递归算法求解指定规模的汉诺塔问题,动态模拟了求解过程中盘片的移动效果。
【期刊名称】《武汉船舶职业技术学院学报》【年(卷),期】2011(010)006【总页数】6页(P55-59,72)【关键词】汉诺塔;二叉树;递归,非递归;可视化;模拟【作者】彭伟【作者单位】武汉城市职业学院,湖北武汉430064【正文语种】中文【中图分类】TP301汉诺塔游戏最早于19世纪出现在欧洲,它展示了一项正在婆罗门寺庙进行的任务:在创世之初,牧师被授予一个铜盘,上面有3根钻石针,在第1根针上叠放着64个碟片,每一个都比它下面的稍小一些,这位牧师被安排了一项任务,那就是将所有的碟片从第1根针移到第3根针,但要遵循的规则是:一次只能移动一个碟片,并且不允许将任何一个碟片放在比它小的碟片上面。
【C语言程序设计】汉诺塔问题,用C语言实现汉诺塔!
![【C语言程序设计】汉诺塔问题,用C语言实现汉诺塔!](https://img.taocdn.com/s3/m/3f75a7ecc9d376eeaeaad1f34693daef5ef71300.png)
【C语⾔程序设计】汉诺塔问题,⽤C语⾔实现汉诺塔!汉诺塔问题是指:⼀块板上有三根针 A、B、C。
A 针上套有 64 个⼤⼩不等的圆盘,按照⼤的在下、⼩的在上的顺序排列,要把这 64 个圆盘从 A 针移动到 C 针上,每次只能移动⼀个圆盘,移动过程可以借助 B 针。
但在任何时候,任何针上的圆盘都必须保持⼤盘在下,⼩盘在上。
从键盘输⼊需移动的圆盘个数,给出移动的过程。
算法思想对于汉诺塔问题,当只移动⼀个圆盘时,直接将圆盘从 A 针移动到 C 针。
若移动的圆盘为 n(n>1),则分成⼏步⾛:把 (n-1) 个圆盘从 A 针移动到 B 针(借助 C 针);A 针上的最后⼀个圆盘移动到 C 针;B 针上的 (n-1) 个圆盘移动到 C 针(借助 A 针)。
每做⼀遍,移动的圆盘少⼀个,逐次递减,最后当 n 为 1 时,完成整个移动过程。
因此,解决汉诺塔问题可设计⼀个递归函数,利⽤递归实现圆盘的整个移动过程,问题的解决过程是对实际操作的模拟。
程序代码#include <stdio.h>int main(){int hanoi(int,char,char,char);int n,counter;printf("Input the number of diskes:");scanf("%d",&n);printf("\n");counter=hanoi(n,'A','B','C');return0;}int hanoi(int n,char x,char y,char z){int move(char,int,char);if(n==1)move(x,1,z);else{hanoi(n-1,x,z,y);move(x,n,z);hanoi(n-1,y,x,z);}return0;}int move(char getone,int n,char putone){static int k=1;printf("%2d:%3d # %c---%c\n",k,n,getone,putone);if(k++%3==0)printf("\n");return0;}调试运⾏结果:当移动圆盘个数为 3 时,具体移动步骤如下所⽰:Input the number of diskes:31: 1 # A---C2: 2 # A---B3: 1 # C---B4: 3 # A---C5: 1 # B---A6: 2 # B---C7: 1 # A---C总结:本实例中定义的 hanoi() 函数是⼀个递归函数,它有四个形参"n""x""y""z"。
C语言程序设计课程设计报告---汉诺塔问题
![C语言程序设计课程设计报告---汉诺塔问题](https://img.taocdn.com/s3/m/7c453961a45177232f60a273.png)
XXXX大学计算机科学与技术学院课程设计报告2012 — 2013学年第一学期课程名称C/C++高级语言程序设计课程设计设计题目小游戏和图形处理汉诺塔问题学生姓名XXX学号XXXXXXX专业班级XXXXXXXXXXX指导教师XX2012 年X 月XX 日目录一、课程设计问题描述 (1)1、课程设计题目 (1)2、设计任务要求 (1)二、总体设计 (1)1、设计思路 (1)2、汉诺塔求解流程图 (2)三、详细设计 (2)1、汉诺塔问题描述 (2)2、算法分析 (3)3、实现递归的条件 (4)4、用C语言实现 (4)四、程序运行结果测试与分析 (4)1、打开Microsoft Visual C++ 6.0操作平台输入以下的源代码 (4)2、编译源代码 (5)3、组建 (5)4、执行 (5)5、运行结果 (6)6、按任意键结束程序 (7)五、结论与心得 (7)六、参考文献 (8)七、附录:程序源代码 (8)一、课程设计问题描述1、课程设计题目汉诺塔问题2、设计任务要求输入盘子数(2个以上有效),移动速度,开始演示汉诺塔移动的步骤,要求:盘子A,B,C柱需要自己绘制,初始时盘子在A柱上通过B柱最终移动到C 柱上,显示出盘子在几个柱之间的移动过程。
二、总体设计1、设计思路对于一个类似的这样的问题,任何一个人都不可能直接写出移动盘子的每一个具体步骤。
可以利用这样的统筹管理的办法求解:我们假设把该任务交给一个僧人,为了方便叙述,将他编号为64。
僧人自然会这样想:假如有另外一个僧人能有办法将63个盘子从一个座移到另一个座,那么问题就解决了,此时僧人A B C64只需这样做:(1).命令僧人63将63个盘子从A座移到C座(2).自己将最底下的最大的一个盘子从A座移到C座(3).再命令僧人63将63个盘子从B座移到C座为了解决将63个盘子从A座移到B座的问题,僧人63又想:如果能再有一个僧人62能将62个盘子移动到另一座,我就能将63个盘子从A座移动到B座。
汉诺塔游戏用C编
![汉诺塔游戏用C编](https://img.taocdn.com/s3/m/5d1ceca92b160b4e777fcf2d.png)
#ifndef HANIO_H_#define HANIO_Hclass Stack{private:enum{ MAX=50 };int m_node[MAX];int m_top;int m_size;int m_index;public:Stack();~Stack() { };bool Isfull() { return m_top==MAX-1 ;}; ush(i); utPrint();}void Hanio::print(char ch,int n){for(int i=1;i<=n;i++)std::cout<<ch;}void Hanio::DrawPaletes(char ch){int max;max=m_stack[0].Size()>m_stack[1].Size() ? m_stack[0].Size() : m_stack[1].Size();max=m_stack[2].Size()>max ? m_stack[2].Size() : max;etIndex(max-1);m_stack[1].SetIndex(max-1);m_stack[2].SetIndex(max-1);for(int i=1;i<=max;i++){int data1=m_stack[0].MoveToNext();int data2=m_stack[1].MoveToNext();int data3=m_stack[2].MoveToNext();if(data1==0)print(' ',20);else{print(' ',10-data1);print(ch,2*data1);print(' ',10-data1);}if(data2==0)print(' ',20);else{print(' ',10-data2);print(ch,2*data2);print(' ',10-data2);}if(data3==0)print(' ',20);else{print(' ',10-data3);print(ch,2*data3);print(' ',10-data1);}std::cout<<std::endl;}}bool Hanio::MoveFromTo(int x,int y){m_steps++; sempty()){std::cout<<x<<" pallete is empty ! continue !"<<std::endl;std::();return false;}if(m_stack[y].Isempty()){int data;m_stack[x].Pop(&data);m_stack[y].Push(data);return true;}else{if(m_stack[x].TopValue()>m_stack[y].TopValue()){std::cout<<"The board can't move from "<<x<<" plate to " <<y<<" plate!"<<std::endl;std::();return false;}else{int data;m_stack[x].Pop(&data);m_stack[y].Push(data);return true;}}}bool Hanio::IsFinished(){return m_stack[2].Top()==m_num-1;}void Hanio::GameStart(){using namespace std;UINT StartTime=::GetTickCount();UINT EndTime;while(1){system("cls");print('-',80);cout<<"steps: "<<m_steps; print(' ',20);cout<<"Used time: "<<m_times<<endl;print('-',80);cout<<endl; cout<<endl; print(' ',10); cout<<"A";print(' ',19); cout<<"B"; print(' ',19);cout<<"C"<<endl<<endl;Hanio::DrawPaletes();cout<<endl; cout<<endl;print('-',80);."<<endl;();}char ch1=toupper(szCommand[0]);char ch2=toupper(szCommand[1]);if( ch1=='A' && ch2=='B')Hanio::MoveFromTo(0,1);else if ( ch1=='A' && ch2=='C')MoveFromTo(0,2);else if ( ch1=='B' && ch2=='A')MoveFromTo(1,0);else if ( ch1=='B' && ch2=='C')MoveFromTo(1,2);else if ( ch1=='C' && ch2=='A')MoveFromTo(2,0);else if ( ch1=='C' && ch2=='B')MoveFromTo(2,1);else{cout<<"Bad command !"<<endl;();}每天只能动一个盘,而且只能从最上面的铁盘开始搬动."<<endl; print(' ',5);cout<<"2. 必须维持较小的铁盘在上方的原则"<<endl;cout<<endl;cout<<"这两个原则,则当24个铁盘完全般到另一个木桩时,世界就回永久和平!!"<<endl;cout<<"游戏的玩法可以在命令行中输入HELP查看"<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<endl;cout<<"再此输入你要搬的铁盘数(建议在1--10值间,太多回花费很长时间的)"<<endl; print('=',80);cout<<">>";cin>>number;();system("cls");return number;}。
汉诺塔问题非递归算法c语言
![汉诺塔问题非递归算法c语言](https://img.taocdn.com/s3/m/c161eeb1900ef12d2af90242a8956bec0875a562.png)
汉诺塔问题非递归算法c语言汉诺塔问题是一个经典的数学问题,也是一个常见的编程练习题。
在这个问题中,有三根柱子和一些圆盘,圆盘的大小不一,从小到大依次叠放在一根柱子上。
目标是将所有的圆盘从一根柱子移动到另一根柱子,移动过程中要保证大的圆盘在小的圆盘上面。
同时,每次只能移动一个圆盘,且不能把一个大的圆盘放在一个小的圆盘上面。
在解决汉诺塔问题时,通常采用递归算法。
但是递归算法的效率并不高,因为每次递归都会产生额外的函数调用,增加了系统的开销。
因此,我们可以通过非递归的方式来解决汉诺塔问题,提高算法的效率。
以下是一个用C语言实现的汉诺塔问题的非递归算法:```c#include <stdio.h>#include <stdlib.h>typedef struct {int n;char start, end, temp;} StackNode;typedef struct {StackNode data[100];int top;} Stack;void push(Stack *s, StackNode node) {s->data[s->top++] = node;}StackNode pop(Stack *s) {return s->data[--s->top];}void hanoi(int n, char start, char end, char temp) {Stack s;s.top = 0;StackNode node;node.n = n;node.start = start;node.end = end;node.temp = temp;push(&s, node);while (s.top > 0) {node = pop(&s);if (node.n == 1) {printf("Move disk 1 from %c to %c\n", node.start, node.end); } else {StackNode node1, node2, node3;node1.n = node.n - 1;node1.start = node.temp;node1.end = node.end;node1.temp = node.start;push(&s, node1);node2.n = 1;node2.start = node.start;node2.end = node.end;node2.temp = node.temp;push(&s, node2);node3.n = node.n - 1;node3.start = node.start;node3.end = node.end;node3.temp = node.temp;push(&s, node3);}}}int main() {int n;printf("Enter the number of disks: "); scanf("%d", &n);hanoi(n, 'A', 'C', 'B');return 0;}```在这个非递归算法中,我们使用了一个栈来模拟递归的过程。
汉诺塔问题的递归解法和非递归解法(python语言实现)
![汉诺塔问题的递归解法和非递归解法(python语言实现)](https://img.taocdn.com/s3/m/52edb898d1d233d4b14e852458fb770bf78a3bd8.png)
汉诺塔问题的递归解法和⾮递归解法(python语⾔实现)1. 汉诺塔问题的⾮递归解法(python语⾔类解法)#!/usr/bin/env python#coding:utf-8import sysimport timereload(sys)sys.setdefaultencoding('utf-8')class Mycolumns(object):val=0#__slots__ = ['plates','name']def __init__(self,name='',plates_num=0): = nameself.plates = []if plates_num > 0 :for i in range(0,plates_num):self.plates.append(n-i)@staticmethoddef fun():Mycolumns.val +=1print"this is the %d th time to move" %(Mycolumns.val)【这段可以⽤类⽅法代替】【@classmethoddef fun(cls):cls.val +=1print"this is the %d th time to move" %(cls.val)】def initialize(n):stack = []mycolumn1 = Mycolumns('A',n)if n%2 == 0:mycolumn2 = Mycolumns('B')mycolumn3 = Mycolumns('C')index = 2else:mycolumn2 = Mycolumns('C')mycolumn3 = Mycolumns('B')index = 1stack.append(mycolumn1)stack.append(mycolumn2)stack.append(mycolumn3)return stack,indexdef nowcolumn(i,stack):for item in stack:if i in item.plates:return itemdef nextcolumn(i,stack):for item in stack:if i in item.plates:if i%2!=0:next = (stack.index(item)+1)%3else:next = (stack.index(item)+2)%3#print "%d next column is %s"%(i,stack[next].name)return stack[next]def move(nowcolumn,nextcolumn):n = nowcolumn.plates.pop()nextcolumn.plates.append(n)print "move plate %d from %s to %s" %(n,,)Mycolumns.fun()def hannuoyi(n):stack,index = initialize(n)#max = pow(2,n)-1#k =0#while(k<max): FINAL = [] for i in range(0,n): FINAL.append(n-i) while(stack[index].plates!=FINAL):for i in range(1,n+1):#print "i value is %d" %(i)if(nowcolumn(i,stack).plates.index(i)==len(nowcolumn(i,stack).plates)-1 and (nextcolumn(i,stack).plates==[] or i< nextcolumn(i,stack).plates[-1])): move(nowcolumn(i,stack),nextcolumn(i,stack))#k = k+1else:pass#print"can not move plate %d" %(i)print stack[0].plates,stack[0].nameprint stack[1].plates,stack[1].nameprint stack[2].plates,stack[2].nameif __name__=="__main__":n=3hannuoyi(n) 2. 汉诺塔问题的⾮递归解法(python语⾔过程式解法)#!/usr/bin/env python#coding:utf-8import sysimport timereload(sys)sys.setdefaultencoding('utf-8')global aa =0def fun():global aa = a+1print"this is the %d th time to move" %(a)def nowcolumn(i,stackA,stackB,stackC):if i in stackA:return stackAelif i in stackB:return stackBelse:return stackCdef nextcolumn(n,i,stackA,stackB,stackC):if n%2==0:if i in stackA:if i%2!=0:newcolumn = stackBelse:newcolumn = stackCif i in stackB:if i%2!=0:newcolumn = stackCelse:newcolumn = stackAif i in stackC:if i%2!=0:newcolumn = stackAelse:newcolumn = stackBelse:if i in stackA:if i%2==0:newcolumn = stackBelse:newcolumn = stackCif i in stackB:if i%2==0:newcolumn = stackCelse:newcolumn = stackAif i in stackC:if i%2==0:newcolumn = stackAelse:newcolumn = stackBreturn newcolumndef move(nowcolumn,nextcolumn):n = nowcolumn.pop()nextcolumn.append(n)print "move plate %d" %(n)fun()def hannuoyi(n):stackA = []stackB = []stackC = []FINAL = []for i in range(0,n):stackA.append(n-i)FINAL.append(n-i)print stackA,stackB,stackC,FINALwhile(stackC!=FINAL):for i in range(1,n+1):print "i value is %d" %(i)if(nowcolumn(i,stackA,stackB,stackC).index(i)==len(nowcolumn(i,stackA,stackB,stackC))-1 and (nextcolumn(n,i,stackA,stackB,stackC)==[] or i< nextcolumn(n,i,stackA,stackB,stackC)[-1])):move(nowcolumn(i,stackA,stackB,stackC),nextcolumn(n,i,stackA,stackB,stackC))else:print"can not move plate %d" %(i)print stackA,stackB,stackCif __name__=="__main__":n=6hannuoyi(n)2. 汉诺塔问题的递归解法(python语⾔)#!/usr/bin/env python#coding:utf-8import sysreload(sys)sys.setdefaultencoding('utf-8')global aa =0def fun():global aa = a+1def hannuoyi(n,A,B,C):if n==1:move(1,A,C)else:hannuoyi(n-1,A,C,B)move(n,A,C)hannuoyi(n-1,B,A,C)def move(n,tempA,tempB):print "move plate %d from column %s to column %s" %(n,tempA,tempB)fun()if __name__=="__main__":hannuoyi(3,'A','B','C')print "total:we need %d steps"%(a)。
由汉诺塔游戏想到的汉诺塔简单非递归算法
![由汉诺塔游戏想到的汉诺塔简单非递归算法](https://img.taocdn.com/s3/m/bf599a9351e79b896802263c.png)
1的数 组 元 素 中 ,第 二 大 的 盘 子 存 放 在 下 标 为 2的数 组 元 素 中 ,依 此 类 推 。 下 标 为 0的 第 一 个 数 组 元 素 中 存 放 本 数 组 中 盘 子 的个 数 。假 设 有 k个 盘 子 ,则 初 始 状 态 数 组 a的第 一 个 元 素 a0的 值 为 k 表 示 有 k个 盘 [ 1 ( 子 ) al的 值 也 为 k 表 示 最 大 的 盘 子 k , [】 值 为 ,l 】 ( ) a2的 k1 a 1 一 , [ 的值 为 1 k ,数 组 b和 C的 所 有 元 素 全 为 0 。这
维普资讯
《 农业 网络信息》 0 8年第 6期 交 流 园地 20
由汉诺塔游 戏想 到的汉诺 塔简 单非递归算法
张 洪 庆
( 龙 江农业 经 济 职业 学院 ,黑 龙江 牡丹 江 17 4 ) 黑 5 0 1 摘 要: 汉诺塔 问题是 一个 古典 的数 学问题 , 也是 程 序设 计 中的经典 递 归问题 , 递 归算 法 由于 简 洁 清晰 , 大 家所 熟 悉 其 为
p o e u e e in.be a s e u sv lo i m ,a r a la t t u o i’ sm pe a d l a,wrte y a r ltv l r c d r s d sg c u e rc r ie ag rt h s we a e f mi r wih i i d e t t S i l n ce r itn b eaiey sm pe p o e u e wi eiin y o a i p to muc moy s a e n ti p r h te tc lm o eig o h we f i l r c d r t d fce c ftkng u o h h me r p c .I h spa e ,t e mah maia d ln fte To ro
汉诺塔问题(Hanoi)的C++代码实现
![汉诺塔问题(Hanoi)的C++代码实现](https://img.taocdn.com/s3/m/3199530811a6f524ccbff121dd36a32d7375c7d2.png)
汉诺塔问题(Hanoi)的C++代码实现1 #include <iostream>2using namespace std;3//第⼀个塔为初始塔,第⼆个塔为中转塔,第三个塔为⽬标塔45int i = 1; //记录步数6void move(int n,char from,char to) //将编号为N的盘⼦由from塔转移到to塔7{8 cout<<"第"<<i++<<"步:将"<<n<<"号盘⼦"<<from<<"---->"<<to<<endl; //输出实例:第1步:将1号盘⼦A---->C9}1011void hanoi(int n,char from,char denpend_on,char to) //汉诺塔递归函数,参数依次为盘⼦数,起始塔,中转塔,⽬标塔12{13if(n==1)14 {15 move(1,from,to); //当需要移动的盘⼦数为1的时候,将此盘⼦从起始塔直接移动到⽬标塔16 }17else18 {19 hanoi(n-1,from,to,denpend_on); //当需要移动的盘⼦数不为1的时候,20//先将除最下⾯的盘⼦外的盘⼦从起始塔借助⽬标塔移动到中转塔21 move(n,from,to); //将剩下的最后的塔直接从起始塔移动到⽬标塔22 hanoi(n-1,denpend_on,from,to); //将之前移⾛的n-1个盘⼦从中转塔借助起始塔移动⾄⽬标塔23 }24}2526int main()27{28int n = 0;//n为盘⼦数29 cout<<"请输⼊盘⼦的个数:";30 cin>>n;31while(n<=0)//⾮法盘⼦数判断32 {33 cout<<"盘⼦的个数不应⼩于1,请重新输⼊:";34 cin>>n;35 }36if(n>0)37 {38char x='A',y='B',z='C';39 cout<<"盘⼦移动情况如下:"<<endl;40 hanoi(n,x,y,z); //调⽤hanoi函数41return0;42 }43 }运⾏结果:递归实现,未对过程进⾏存储。
汉诺塔实验报告
![汉诺塔实验报告](https://img.taocdn.com/s3/m/a7198258cd1755270722192e453610661fd95a12.png)
一、实验目的1. 理解汉诺塔问题的基本原理。
2. 掌握分治算法在解决汉诺塔问题中的应用。
3. 通过编程实现汉诺塔问题的递归与非递归解法。
4. 分析汉诺塔问题的移动次数,并探讨优化方案。
二、实验原理汉诺塔问题是一个经典的递归问题,描述为:有n个大小不同的圆盘,它们分别放在三根柱子上,初始状态为第1根柱子从上到下依次排列。
要求按照以下规则将所有圆盘移动到第3根柱子上:1. 一次只能移动一个圆盘。
2. 任何时候,在某一根柱子上的圆盘都必须是按照从上到下依次递减的顺序排列。
3. 不能将一个较大的圆盘放在一个较小的圆盘上面。
汉诺塔问题可以通过分治法来解决。
分治法的基本思想是将大问题分解成小问题,分别解决小问题,最后将小问题的解合并成大问题的解。
对于汉诺塔问题,我们可以将其分解为以下三个子问题:1. 将n-1个圆盘从第1根柱子移动到第2根柱子。
2. 将第n个圆盘从第1根柱子移动到第3根柱子。
3. 将n-1个圆盘从第2根柱子移动到第3根柱子。
通过递归地解决这三个子问题,我们可以得到汉诺塔问题的解。
三、实验内容1. 递归解法我们可以使用递归函数来实现汉诺塔问题的递归解法。
以下是C语言实现的示例代码:```c#include <stdio.h>void hanoi(int n, char from, char to, char aux) {if (n == 1) {printf("Move disk 1 from %c to %c\n", from, to);return;}hanoi(n - 1, from, aux, to);printf("Move disk %d from %c to %c\n", n, from, to);hanoi(n - 1, aux, to, from);}int main() {int n;printf("Enter the number of disks: ");scanf("%d", &n);hanoi(n, 'A', 'C', 'B');return 0;}```2. 非递归解法除了递归解法,我们还可以使用栈来实现汉诺塔问题的非递归解法。
Hanoi塔问题的非递归算法分析
![Hanoi塔问题的非递归算法分析](https://img.taocdn.com/s3/m/f1e091cc6137ee06eff918fc.png)
l 问题的提出
Ha o塔 问题是源 于一个 古老 的传说,在l 世纪末 ,欧 ni 9 洲出现 了一种名为Ha o塔的游戏 ,这种游戏最 早来 源于布 ni 拉玛神庙 的教 士。有三根石针 、B 、C,在A 上放有6 个 针 4
1 步操作。例如 当N 4 ,Ha o塔游戏过程如图2 - =时 ni 所示。 可见 ,通过此 表的移动过程可 以看 出,当N 4 ,共移 - =时
由C 针移至 针 。
那一步 的操作对象 是,_号盘 ,起 点 是 ,终 点是c 。按 v1 针 针 照这种 方式 ,从 中心 位置开始 ,逐渐 向两瑞扩 展 ,最终 能 够 确定所有操作步起 点和 终点。
3算法的实现
利用函数调用 法来实现Ha o塔非递归算法 ni
v i eetn m. n a : od d l i t it 1 manf i 1 f it , n n m=I i ,;
2 解决问题的方案 . 2
f1 有~ l设 个盘 子按照规则从 第 1 针移动 到第3 针所需要 的最 少操 作 数 为 ,则根 据Ha o 塔 的递 归性 和对 称性 可 ni 知,数列 1 须满足 :AIl = 时,而 当n 时有 - 4 l ≥2 .2 + ;由 A= n I - 可 ̄A+12/ . l;这 说明数列 nl是 以2 l + . - ( + l 11 +l 为公 比而 以 。12 + - 为首 项的等 比数列,所 以 + _ ¨ n l 22 ≥l, 1 lA l ≥l。所 以解决N l . p 1 个盘 子的Ha o塔 问题至少需要 ni
关键词:汉诺塔;递归;非递归;时间复杂性
中图分类号 :T 3 1 P 0. 6 文献标 识码 :A
.
文章编号 :10 .8 42 0 )20 4 .2 0 88 1(0 60 0 00
Hanoi塔问题一种非递归算法的C++实现
![Hanoi塔问题一种非递归算法的C++实现](https://img.taocdn.com/s3/m/ea4b2a7331b765ce05081460.png)
{
h n in一 1 o e,h e , WO) a o( ,n tret ; mo e o e t r Байду номын сангаас v ( n ,h e ;
1 Ha o ( 诺 ) n i汉 问题 的递 归 算 法
Ha o( n i汉诺 ) 问题 是 这 样 的 : 代 有 一个 梵 塔 , 古 其
) )
I lme t to fC + + t a eA n—r c r ieAlo ih mp e n a in o o M k No e u sv g rt m
a o t To r o a i b u we f H no
贺存 薪 ( 京 交通 大学 北京 北 10 4 ) 0 0 4
Ha o 塔 问题 是 递 归 程 序 设 计 中 的 经 典 问题 之 ni
一
# i l de is r a . nc u < o t e m h>
,
大部 分讲 递 归程 序 ( 算 法 ) 计 的书 都 以 Ha o 或 设 ni
i l e v i v ( h rg t n c a u o e n i o d mo e c a e o e, h rp t n ) n
a g rt m r a ie y b i to h a as r c u e o i a y—t e , n r s n s t e s u c r g a o lo i h c e tv l y d n f e d t t u t r fb n r t r e a d p e e t h o r e p o r m fC+ + t a e t e a g rt m. Om k h lo i h Th s a g rt m a n’ e l r a e h a ia y—t e h sc l a d i i d fe e tfo t e t a i o a i a y t e tu t r i lo i h h s tr a l c e t d t e s me b n r y r e p y i l n s if r n r m h r d t n l n r - r e s r c u e a y, t i b
C语言中的递归程序可以用非递归算法实现吗
![C语言中的递归程序可以用非递归算法实现吗](https://img.taocdn.com/s3/m/a854101176232f60ddccda38376baf1ffc4fe32f.png)
C语言中的递归程序可以用非递归算法实现吗C语言中的递归程序可以用非递归算法来实现。
递归是一种使用函数自身调用的编程技巧,通过将一个问题拆分成更小的子问题来解决。
然而,递归在处理大规模问题或者嵌套过深的情况下会导致栈溢出,并且递归调用的开销较大。
因此,一些复杂的递归程序可以通过非递归算法来重新实现,以降低开销和避免栈溢出。
一种常见的非递归替代方法是使用循环结构和栈数据结构来模拟递归函数的行为。
栈的数据结构可以保存每次递归调用过程中的参数和局部变量,从而避免函数调用的开销。
下面以经典的阶乘函数为例,展示如何将递归程序转化为非递归算法。
递归版阶乘函数:```cint factorial(int n)if (n == 0)return 1;} elsereturn n * factorial(n-1);}```非递归版阶乘函数:```cint factorial(int n)int result = 1;while (n > 0)result *= n;n--;}return result;```这个非递归版本的阶乘函数使用了一个循环来迭代计算乘法,并使用一个变量 `result`来保存当前的结果。
每次迭代,`n` 减1,并将当前结果乘以 `n`,直到 `n` 为0。
类似的,其他的递归函数也可以通过类似的方式来转化为非递归版本。
需要注意的是,非递归版本通常需要额外的变量来保存中间结果,并使用循环结构来模拟函数的递归调用过程。
通过将递归程序转化为非递归算法,可以避免栈溢出和函数调用开销,从而提高程序的效率和性能。
但是非递归算法通常会增加代码的复杂度和可读性,因此开发者在选择使用递归还是非递归算法时应该权衡这些因素。
总而言之,C语言中的递归程序可以通过非递归算法来实现。
通过使用循环结构和栈数据结构,可以模拟递归函数的行为,并避免由于递归调用导致的栈溢出和函数调用开销。
但是需要注意的是,非递归算法可能会增加代码的复杂度和可读性,开发者需要在性能和代码清晰度之间进行权衡。
汉诺塔问题非递归算法
![汉诺塔问题非递归算法](https://img.taocdn.com/s3/m/99f0f6bcf605cc1755270722192e453610665b35.png)
汉诺塔问题非递归算法
汉诺塔问题是一个经典的递归算法问题,但也可以使用非递归的方式解决。
下面是一种非递归算法的实现思路:
1. 创建三个栈,分别命名为A、B、C,表示三个柱子。
2. 对于n个盘子的汉诺塔问题,首先将所有盘子按从大到小的顺序依次压入栈A中。
3. 定义一个变量count,用来记录移动步数,初始值为0。
4. 如果n为奇数,则执行步骤5;如果n为偶数,则执行步骤6。
5. 循环执行以下操作:
5.1 将栈A的栈顶元素弹出,放入栈B中;
5.2 将栈A中剩余的n-1个盘子移到栈C中;
5.3 将栈B中的盘子移到栈C中;
5.4 将栈A作为辅助栈,栈B作为目标栈,栈C作为源栈,重复步骤5.1~5.3,直到栈A为空。
6. 循环执行以下操作:
6.1 将栈A的栈顶元素弹出,放入栈C中;
6.2 将栈A中剩余的n-1个盘子移到栈B中;
6.3 将栈C中的盘子移到栈B中;
6.4 将栈A作为辅助栈,栈C作为目标栈,栈B作为源栈,重复步骤6.1~6.3,直到栈A为空。
通过上述非递归算法,可以按照汉诺塔问题的规则将所有的盘子从栈A移动到栈B,并记录移动的步骤数。
C语言递归调用实例——汉诺塔问题动画实现(附完整代码)
![C语言递归调用实例——汉诺塔问题动画实现(附完整代码)](https://img.taocdn.com/s3/m/b75e0bec700abb68a982fb68.png)
二、程序框架
古人云,不谋全局者,不足谋一域。同样,在编写代码之前,我们必 须得有个大体的思路和整体上的把握。不能一上来就稀里糊涂地乱敲一通。 当然,这里我也只能仅仅谈自己的个人想法,不一定就是最优的解决方案, 还希望能和大家一起相互交流,共同进步。整个程序的框架,我把它分为 动画效果和核心算法两大部分。我首先实现的是动画效果部分,等能够实 现盘子的随意移动后,我才开始研究核心算法的实现。这样一来,在核心 算法部分,我们正好可以利用前面的动画效果来直观地反映出我们的思路, 有助于代码的调试和缩短程序的开发周期。为了尽量减少废话,我们可以 用一张图来进行表示:
图 1-1 移动第一个圆盘..................................................................................................................... 4 图 1-2 移动第二个圆盘...................................................................................................................... 5 图 1-3 移动最后一个圆盘................................................................................................................. 6
能移动一个圆盘,且圆盘在放到棒上时,大的不能放在小的上面。中间的一根
棒作为辅助移动用。” 事实上,对此曾经有人作过分析,按这个规则,众僧耗尽毕生精力也
不可能完成圆盘的移动,因为需要移动圆盘的次数是一个天文数字 18446744073709551615(64 个圆盘需要移动的次数为 2 的 64 次方)。假设 1us 进行一次移动,也需要约一百万年的时间,使用计算机也很难解决 64
汉诺(Hanoi)塔问题(C#版)
![汉诺(Hanoi)塔问题(C#版)](https://img.taocdn.com/s3/m/a279b13586c24028915f804d2b160b4e777f815d.png)
汉诺(Hanoi)塔问题(C#版)
⼀个只能⽤递归解决的数学问题;问题描述:古代有⼀个梵塔,塔内有3个座,A、B、C,开始时A座有64个盘,盘⼦⼤⼩不等,⼤的在上,⼩的在下。
有⼀个⽼和尚想把这64个盘⼦从A座移到C座(如图所⽰),但每次只允许移动⼀个盘,且在移动过程中在3个座上始终保持⼤盘在下,⼩盘在上。
在移动地程中可以⾏⽤B座,要求编程序打印出移动的步骤。
逆向推理:1.假如⼀个和尚能把上⾯63个盘⼦先搬到B座,第⼆个和尚再把最⼤的那个移到C,第三个和尚再把63个盘⼦移到C座;⾄此整个⼯作就完成的。
2.问题是怎么才能把63个盘⼦移到B座,按照同样的⽅法,先把62个盘⼦选移到C座
,再把第63个盘⼦移到B座,最后再将62个盘⼦移到B座。
3……如此类推;
4.从上⾯分析可以看出:只有等后⾯那个和尚搬完盘⼦,前⾯的和尚才能够去完成任。
让我们来栈的数据结构:数据的处理只在⼀端处理,且是先进后出。
所以⽤递归的⽅法去处理是正确的。
(汉诺塔图)
汉诺塔问题解决⽅案
如果你发现有什么错误之处,请指出!谢谢了。
hanoi塔递归算法c语言
![hanoi塔递归算法c语言](https://img.taocdn.com/s3/m/7e0ac2a950e79b89680203d8ce2f0066f53364fd.png)
hanoi塔递归算法c语言Hanoi塔是一种经典的数字益智游戏,它来源于法国数学家Lucas的BrainVita游戏,被称为“汉诺威塔问题”或“汉诺塔问题”。
该游戏由三个柱子和几个圆盘组成,最初时,圆盘按半径从大到小依次放在一个柱子上(逆序排列),游戏的目标则是将这些圆盘移动到另一个柱子上,最终使得其按半径从小到大依次排列。
在移动整个圆盘的过程中,必须遵循以下规定:1. 每次只能移动一个圆盘;2. 圆盘可以放置在任何柱子上;3. 不能将一个大的圆盘放在较小的圆盘之上。
为了解决这一难题,Hanoi塔问题引入了递归算法,这也是大多数编程语言中最常使用的算法之一。
在C语言中,Hanoi塔问题可以用以下代码实现:```c#include<stdio.h>void move(int n, char x, char y, char z){if(n == 1){printf("%c-->%c\n", x, z);}else{move(n-1, x, z, y);printf("%c-->%c\n", x, z);move(n-1, y, x, z);}}int main(){int n;printf("请输入盘子数:");scanf("%d", &n);printf("移动的步骤如下:\n");move(n, 'A', 'B', 'C');return 0;}```在这个程序中,我们首先定义了一个函数`move()`,该函数接受四个参数:圆盘的数量`n`和字母标识符`x`、`y`、`z`,它们分别代表三个柱子。
在函数中,我们使用了条件判断语句,如果只有一个圆盘,我们直接将其从柱子`x`移动至柱子`z`上。
否则,我们需要进行3个步骤:1. 将n-1个圆盘从柱子`x`移动至柱子`y`上;2. 将第n个圆盘从柱子`x`移动至柱子`z`上;3. 将n-1个圆盘从柱子`y`移动至柱子`z`上。
汉诺塔c语言程序代码
![汉诺塔c语言程序代码](https://img.taocdn.com/s3/m/a1ef675458fafab068dc022e.png)
汉诺塔c语言程序代码(通过vc++6.0验证)(附讲解)让我们先看看代码吧#include <stdio.h>int hj(int a,int b, int c,int i){int t;if(i==1)printf("%d->%d\n",a,c);else{t=c;c=b;b=t;hj(a,b,c,i-1);printf("%d->%d\n",a,b);t=a;a=c;c=t;t=b;b=c;c=t;hj(a,b,c,i-1);return 0;}}main(){int a,b,c,i;a=1;b=2;c=3;printf("请输入汉诺塔的盘数");scanf("%d",&i);hj(a,b,c,i);return 0;}以上是汉诺塔的代码,该程序主要是运用了递归的思想,比如数学中的f(x)=f(x-1)+f(x-2),在本程序中为:int hj(int a,int b, int c,int i){int t;if(i==1)printf("%d->%d\n",a,c);else{t=c;c=b;b=t;hj(a,b,c,i-1);也就是说,我们在这个函数中再次调用这个函数,相当于一个循环,而在再次调用的过程中,i的值变成i-1,就类似于f(x-1),这样层层调用,最终就变成当i=1的时候的值,然后通过运算,计算出想要得到的值。
汉诺塔的数值分析:我们可以发现,当只有一个盘的时候,我们只需要做1->3(就是把第一个柱子上的最顶端的盘移动到第三根柱子,以下不再解释)当有两个盘的时候,是1->2 1->3 2->3三个盘子是:1->3 1->2 3->2 1->3 2->1 2->3 1->3分析一下可以得出以下结论:初始值a=1 b=2 c=3一个盘子就是a->c两个盘子与一个盘子的关系是:第一步:b与c交换值,然后打印a->c第二步:打印a->b第三步:a与c交换值,b与c交换值,打印a->c进一步分析,便可以得出以下结论只要盘子数量为i(i大于1),那么它就有三部分第一部分,b与c交换值,然后运行i-1第二部分,打印a->b第三部分,a与c交换值,b与c交换值,然后运行i-1程序表示便是:if(i==1)printf("%d->%d\n",a,c);else{t=c;c=b;(交换值)b=t;hj(a,b,c,i-1);printf("%d->%d\n",a,b);t=a;a=c;c=t;(a c交换)t=b;b=c;c=t;(b c交换)hj(a,b,c,i-1);。
汉诺塔问题的程序实现(hanoi塔)
![汉诺塔问题的程序实现(hanoi塔)](https://img.taocdn.com/s3/m/8815f6ab1b37f111f18583d049649b6648d709dd.png)
汉诺塔问题的程序实现(hanoi塔)问题重述:有三根柱A、B、C,在柱A上有N块盘⽚,所有盘⽚都是⼤的在下⾯,⼩⽚能放在⼤⽚上⾯。
现要将A上的N块盘⽚移到C柱上,每次只能移动⼀⽚,⽽且在同⼀根柱⼦上必须保持上⾯的盘⽚⽐下⾯的盘⽚⼩,输⼊任意的N,输出移动⽅法。
(注意:这是⼀个古⽼的传说,传说是如果把64个盘⼦由A柱移到了C柱的话,那么世界末⽇就到了,事实上如果要把64个盘⼦从A柱移到C柱的话,即使⽤计算机运算,也要计算数亿年,所以这个预⾔未必不是真实。
)【分析】我们可以这样考虑,当n=1时,我们只要直接将A柱的盘⼦移到C柱,当n>1时,我们可以先把n-1个盘⼦由A柱通过C柱移到B 柱,此时就可以把A柱剩下的最后⼀个盘⼦直接移到C柱,这样接下来只要把n-1个盘⼦通过A柱移到C 柱即可,如果就构成了递归的思路,我们可以定义个移动过程mov(n,a,b,c)表⽰将n个盘⼦从a通过b移到c1.只要求输出搬运的次数#includeusing namespace std;int m=0;void move(){m++;}void I(int n){if(n==1)move();else{I(n-1);move();I(n-1);}}int main(){I(3);cout<cout<<"输出完毕!"<return 0;}更加简单的⽅法!#includeusing namespace std;int fact(int n){if(n==1)return(1);elsereturn((2*fact(n-1)+1));}int main(){cout<}2.不仅要求输出搬运的次数,⽽且要输出每个步骤的详细搬运#includeusing namespace std;int m=0;void Move(int n,char x,char y){cout<<"把"<m++;}void Hannoi(int n,char a,char b,char c){if(n==1)Move(1,a,c);else{Hannoi(n-1,a,c,b);Move(n,a,c);Hannoi(n-1,b,a,c);}}int main(){int i;cout<<"请输⼊圆盘数"<cin>>i;Hannoi(3,'a','b','c');cout<<"总的搬运次数"<cout<<"输出完毕!"<return 0;}}另外⼀种不利⽤递归的解法(很抱歉,我⾃⼰也没调出来,实在太复杂了)#includeusing namespace std;//圆盘的个数最多为64const int MAX = 1;//⽤来表⽰每根柱⼦的信息struct st{int s[MAX]; //柱⼦上的圆盘存储情况int top; //栈顶,⽤来最上⾯的圆盘char name; //柱⼦的名字,可以是A,B,C 中的⼀个int Top()//取栈顶元素{return s[top];}int Pop()//出栈{return s[top--];}void Push(int x)//⼊栈{s[++top] = x;}} ;long Pow(int x, int y); //计算x^yvoid Creat(st ta[], int n); //给结构数组设置初值void Hannuota(st ta[], long max); //移动汉诺塔的主要函数int main(void){int n;cin >> n; //输⼊圆盘的个数st ta[3]; //三根柱⼦的信息⽤结构数组存储Creat(ta, n); //给结构数组设置初值long max = Pow(2, n) - 1;//动的次数应等于2^n - 1 Hannuota(ta, max);//移动汉诺塔的主要函数system("pause");return 0;}void Creat(st ta[], int n){ta[0].name = 'A';ta[0].top = n-1;//把所有的圆盘按从⼤到⼩的顺序放在柱⼦A 上for (int i=0; ita[0].s[i] = n - i;//柱⼦B,C 上开始没有没有圆盘ta[1].top = ta[2].top = 0;for (int j=0; jta[1].s[j] = ta[2].s[j] = 0;//若n 为偶数,按顺时针⽅向依次摆放A B Cif (n%2 == 0){ta[1].name = 'B';ta[2].name = 'C';}else //若n 为奇数,按顺时针⽅向依次摆放A C B {ta[1].name = 'C';ta[2].name = 'B';}}long Pow(int x, int y){long sum = 1;for (int i=0; isum *= x;return sum;}void Hannuota(st ta[], long max){int k = 0; //累计移动的次数int i = 0;int ch;while (k < max){//按顺时针⽅向把圆盘1 从现在的柱⼦移动到下⼀根柱⼦ch = ta[i%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " <<"Move disk " << ch << " from " << ta[i%3].name <<" to " << ta[(i+1)%3].name << endl;i++;//把另外两根柱⼦上可以移动的圆盘移动到新的柱⼦上if (k < max){ //把⾮空柱⼦上的圆盘移动到空柱⼦上,当两根柱⼦都为空时,移动较⼩的圆if (ta[(i+1)%3].Top() == 0 ||ta[(i-1)%3].Top() > 0 &&ta[(i+1)%3].Top() > ta[(i-1)%3].Top()){ch = ta[(i-1)%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i-1)%3].name<< " to " << ta[(i+1)%3].name << endl;}else{ch = ta[(i+1)%3].Pop();ta[(i-1)%3].Push(ch);cout << ++k << ": " << "Move disk " << ch << " from " << ta[(i+1)%3].name << " to " << ta[(i-1)%3].name << endl; }}}}补充知识:【典型例题1】求阶乘n!#includeusing namespace std;int fact(int n){if(n==0)return(1);elsereturn(n*fact(n-1)); }int main(){cout<。
3-2汉诺塔的非递归实现
![3-2汉诺塔的非递归实现](https://img.taocdn.com/s3/m/58a8037749d7c1c708a1284ac850ad02de80078c.png)
3-2汉诺塔的⾮递归实现 汉诺塔实现的基本思路是:不断将n个盘的汉诺塔问题转换为2个(n-1)个盘的汉诺塔问题,⽤递归实现⽐较好理解。
设n盘问题为(n, a, b, c),其中参数如下结构体所定义,第⼀个参数表⽰需要移动的盘⼦的数量,第⼆个参数表⽰n个盘⼦起始所在柱⼦a, 第三个参数表⽰会被借⽤的柱⼦b, 第四个参数表⽰这 n个盘⼦所在的⽬标柱⼦c。
递归思路假设(n, a, b, c)表⽰把 a柱⼦上的n个盘借助b柱⼦移动到 c 柱⼦上,这个问题的递归求解⽅式是先把 a 柱⼦的(n-1)盘⼦借助c柱⼦移动到b柱⼦上(n-1, a, c, b),然后把 a 柱⼦剩下的⼀个盘⼦移动到 c 柱⼦上(1, a, b, c),最后把 b 柱⼦上的(n-1)个盘⼦移动到 c 柱⼦上(n-1, b, a, c)则问题求解可转换为对(n - 1, a, c, b)、(1, a, b, c)、(n - 1, b, a, c)这三个问题的求解,其中(1, a, b, c)不需要递归,可直接实现,将n个盘的汉诺塔问题转换为2个(n-1)个盘的汉诺塔问题,然后使⽤递归将(n-1)盘问题转换成(n-2)盘问题,直到盘数为1⾮递归的⽅式 递归⽅式本质上使⽤栈来实现的,所以如果采⽤⾮递归的⽅式也是使⽤栈来辅助实现。
但是若是⽤堆栈来实现的话,当将分解出的上述三个问题压⼊栈时,应该按照“需要先求解的问题后压⼊”的顺序,也就是压⼊顺序为:(n - 1, b, a, c), (1, a, b, c), (n - 1, a, c, b).1 typedef struct { //汉诺塔问题的结构类型2int N;3char A; //起始柱4char B; //借助柱5char C; //⽬标柱67 }ElementType; //汉诺塔问题的结构类型1//借助栈的⾮递归实现2void Hanoi(int n)3 {4 ElementType P, toPush;5 Stack S;67 P.N = n; P.A = 'a'; P.B = 'b'; P.C = 'c';8 S.top = -1;910 Push(&S, P);11while (S.top != -1) //当堆栈不为空时12 {13 P = Pop(&S);14if (P.N == 1)15 printf("%c -> %c\n", P.A, P.C);16else17 {18 toPush.N = P.N - 1;19 toPush.A = P.B; toPush.B = P.A; toPush.C = P.C;20 Push(&S, toPush); //将第⼆个待解⼦问题(n - 1, b, a, c)⼊栈21 toPush.N = 1;22 toPush.A = P.A; toPush.B = P.B; toPush.C = P.C;23 Push(&S, toPush); //将可直接求解的⼦问题(1, a, b, c)⼊栈24 toPush.N = P.N - 1;25 toPush.A = P.A; toPush.B = P.C; toPush.C = P.B;26 Push(&S, toPush); //将第⼀个待解⼦问题(n - 1, a, c, b)⼊栈27 }28 }29 }下⾯是栈的实现和主函数:1 #include <stdio.h>2#define MaxSize 10034 typedef struct {5 ElementType Data[MaxSize];6int top;7 }Stack; //堆栈的标准定义89void Push(Stack *PtrS, ElementType item)10 {11//⼊栈操作12if (PtrS->top == MaxSize)13 {14 printf("The stack is full!\n");15return;16 }17else18 {19 PtrS->Data[++(PtrS->top)] = item;20return;21 }22 }2324 ElementType Pop(Stack *PtrS)25 {26if (PtrS->top == -1)27 {28 printf("The stack is empty!\n");29return ERROR; //ERROR是ElementType的特殊值,标志错误30 }31else32 {33 PtrS->top--;34return (PtrS->Data[PtrS->top + 1]); //或者是return PtrS->Data[PtrS->top--];35 }36 }3738int main()39 {40int n;41 ERROR.N = -1; //ERROR是ElementType的特殊值,标志错误42 scanf_s("%d", &n);43 Hanoi(n);44return0;45 }。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
}
fபைடு நூலகம்ee(S->base);
S->base=NULL;
S->top=NULL;
S->stacksize=0;
return 0;
}
}
int PushStack(Stack *S,int n,char x,char y,char z)
{
if(S->top-S->base==S->stacksize)
{
S->base=(hanoi*)realloc(S->base,(S->stacksize+FPZL)*sizeof(hanoi));
{
if(S->top==S->base)
return 0;
else
{
S->top--;
*n=S->top->n;
*x=S->top->x;
*y=S->top->y;
*z=S->top->z;
return 1;
}
}
int EmptyStack(Stack *S)
{
if(S->base==S->top)
if(!S)
return 0;
if(!InitStack(S))
return 0;
printf("\n\n\t\t请输入汉诺塔的初始盘子数量以及轴的名称:");
scanf("%d%c%c%c",&n,&x,&y,&z);
if(!PushStack(S,n,x,y,z))
return 0;
while(!EmptyStack(S))
汉诺塔非递归算法C语言实现
#include<stdio.h>
#include<stdlib.h>
#define CSZL 10
#define FPZL 10
typedef struct hanoi
{
int n;
char x,y,z;
}hanoi;
typedef struct Stack
{
hanoi*base,*top;
if(!S->base)
return 0;
S->top=S->base+S->stacksize;
S->stacksize+=FPZL;
}
S->top->n=n;
S->top->x=x;
S->top->y=y;
S->top->z=z;
S->top++;
return 1;
}
int PopStack(Stack *S,int *n,char *x,char *y,char *z)
int stacksize;
}Stack;
int InitStack(Stack *S)
{
S->base=(hanoi*)malloc(CSZL*sizeof(hanoi));
if(!S->base)
return 0;
S->top=S->base;
S->stacksize=CSZL;
return 1;
{
if(!PopStack(S,&n,&x,&y,&z))
break;
if(n==1)
{
Move(x,z);
}
else
{
if(!PushStack(S,n-1,y,x,z))
break;
if(!PushStack(S,1,x,y,z))
break;
if(!PushStack(S,n-1,x,z,y))
return 1;
else
return 0;
}
int i=1;
void Move(char x,char z)
{
printf("\n\n\t\t第%d部,从%c移到%c。",i++,x,z);
}
int main()
{
int n;
char x,y,z;
Stack *S;
S=(Stack *)malloc(sizeof(Stack));