汉诺塔问题的非递归算法分析
汉诺塔问题的非递归算法设计及可视化实现

汉诺塔问题的非递归算法设计及可视化实现彭伟【摘要】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根针,但要遵循的规则是:一次只能移动一个碟片,并且不允许将任何一个碟片放在比它小的碟片上面。
课程设计汉诺威塔

汉诺威塔问题的来源和历史背景
01
02
04
03
02
CHAPTER
汉诺威塔问题分析与建模
问题描述
汉诺威塔问题是一个经典的递归问题,涉及三个柱子和一系列大小不同的盘子。目标是将所有盘子从一个柱子移动到另一个柱子,每次只能移动一个盘子,并且任何时候都不能将一个较大的盘子放在较小的盘子上面。
因此,空间复杂度为O(n)。
04
CHAPTER
非递归算法实现与性能比较
将所有盘子按从大到小的顺序依次放入第一个栈
从第一个栈中取出最大的盘子,放入第三个栈
如果第一个栈中还有盘子,则重复以上步骤,直到所有盘子都移动到第三个栈为止
如果第二个栈不为空,则将第二个栈中的所有盘子依次取出并放入第一个栈,直到第二个栈为空
迭代方法
另一种非递归方法是使用迭代方法。可以通过维护一个状态变量来跟踪当前需要执行的操作,并根据状态变量的值选择相应的操作进行执行。这种方法需要仔细地设计状态转移逻辑和操作顺序。
优化与改进
针对非递归算法,可以考虑使用优化技术来提高性能。例如,可以使用动态规划来避免重复计算相同子问题的解,或者使用并行计算来加速算法的执行速度。
课程设计汉诺威塔
目录
引言汉诺威塔问题分析与建模递归算法实现与性能分析非递归算法实现与性能比较汉诺威塔问题拓展与应用课程设计总结与展望
01
CHAPTER
引言
学习和掌握递归算法的基本原理和实现方法
通过解决汉诺威塔问题,提高学生的算法设计和分析能力
培养学生的计算思维和解决问题的能力
汉诺威塔问题的基本规则和玩法
递归终止条件
02
当只有一个盘子时,直接将其移动到目标柱子即可。这是递归的终止条件。
汉诺塔问题

盐城工学院C++课程设计二级学院:信息学院班级:姓名:学号:指导老师:1.报告简介1.1 汉诺塔问题简介在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。
印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔(如下图)。
不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必在大片上面。
当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,梵塔、庙宇和众生都将同归于尽。
故汉诺塔问题又被称为“世界末日问题。
”图1-11.2 问题思想解决为满足题目中盘子的移动问题,必须遵循的条件是:一次仅能移动一个盘,且不允许大盘放在小盘的上面。
设要解决的汉诺塔共有N个圆盘,对A杆上的全部N个圆盘从小到大顺序编号,最小的圆盘为1号,次之为2号,依次类推,则最下面的圆盘的编号为N。
第一步:先将问题简化。
假设A杆上只有一个圆盘,即汉诺塔只有一层N,则只要将1号盘从A杆上移到B杆上即可。
第二步:对于一个有N(N>1)个圆盘的汉诺塔,将N个圆盘分成两部分:“上面的N-1个圆盘”看成一个整体,为了解决N个圆盘的汉诺塔,可以按下面图示的方式进行操作:(1)将A杆上面的N-1个盘子,借助B杆,移到C杆上;图1-2(2)将A杆上剩余的N号盘子移到B杆上;图1-3(3)将C杆上的N-1个盘子,借助A杆,移到B杆上。
图 1-41.3 预期目标运行程序后,首先显示:图 1-5选择 1 后,要求输入盘子的数目,即N输入后,显示递归调用时盘子移动的过程图 1-6继续选择 2 ,要求输入盘子的数目,即P输入后,显示非递归调用时盘子移动过程。
图 1-72.需求分析编写汉诺塔程序用到的知识有:符号常量的定义,循环语句,函数,栈与应用;2.1 符号常量的定义常量就是在程序运行过程中其值不发生变化的量。
汉诺塔问题求解思路

汉诺塔问题求解思路汉诺塔问题是⼀个经典的问题。
汉诺塔(Hanoi Tower),⼜称河内塔,源于印度⼀个古⽼传说。
⼤梵天创造世界的时候做了三根⾦刚⽯柱⼦,在⼀根柱⼦上从下往上按照⼤⼩顺序摞着64⽚黄⾦圆盘。
⼤梵天命令婆罗门把圆盘从下⾯开始按⼤⼩顺序重新摆放在另⼀根柱⼦上。
并且规定,任何时候,在⼩圆盘上都不能放⼤圆盘,且在三根柱⼦之间⼀次只能移动⼀个圆盘。
问应该如何操作?分析如果是初次接触类似的问题,乍看之下肯定会感觉⽆从下⼿。
要把64个圆盘从a柱⼦移动到c柱⼦上,第⼀步应该怎么做?虽然可以肯定,第⼀步唯⼀的选择是移动a最上⾯的那个圆盘,但是应该将其移到b还是c呢?很难确定。
因为接下来的第⼆步、第三步……直到最后⼀步,看起来都是很难确定的。
能⽴即确定的是最后⼀步:最后⼀步的盘⼦肯定也是a最上⾯那个圆盘,并且是由a或b移动到c——此前已经将63个圆盘移动到了c上。
也许你会说,管他呢,先随便试着移动⼀下好了。
如果你这么做,你会发现,接下来你会⾯临越来越多类似的选择,对每⼀个选择都“试”⼀下的话,你会偏离正确的道路越来越远,直到你发现你接下来⽆法进⾏为⽌。
如果将这个问题的盘⼦数量减为10个或更少,就不会有太⼤的问题了。
但盘⼦数量为64的话,你⼀共需要移动约1800亿亿步(18,446,744,073,709,551,615),才能最终完成整个过程。
这是⼀个天⽂数字,没有⼈能够在有⽣之年通过⼿动的⽅式来完成它。
即使借助于计算机,假设计算机每秒能够移动100万步,那么约需要18万亿秒,即58万年。
将计算机的速度再提⾼1000倍,即每秒10亿步,也需要584年才能够完成。
注:在我的笔记本电脑上,每秒⼤约能够移动6~8百万步。
虽然64个盘⼦超出了⼈⼒和现代计算机的能⼒,但⾄少对于计算机来说,这不是⼀个⽆法完成的任务,因为与我们⼈类不同,计算机的能⼒在不断提⾼。
分解问题⼀股脑地考虑每⼀步如何移动很困难,我们可以换个思路。
python汉诺塔非递归算法

python汉诺塔非递归算法如何使用Python编写非递归的汉诺塔算法首先,让我们回顾一下汉诺塔问题的背景。
汉诺塔是一个经典的数学问题,涉及到递归和栈的使用。
问题的目标是将一组不同大小的圆盘从一个柱子移动到另一个柱子,其中有三个柱子可供选择。
在移动过程中,您必须遵守以下规则:1. 您只能移动一个圆盘,并且只能将较小的圆盘放在较大的圆盘上。
2. 您只能在三个柱子之间移动圆盘。
3. 将所有圆盘从一个柱子移动到另一个柱子上是成功的。
使用递归算法可以很容易地解决这个问题。
然而,递归算法在处理大量圆盘时可能会导致递归深度过大,从而消耗大量的内存和计算时间。
因此,我们需要采用非递归的方法来解决这个问题。
接下来,让我们一步一步地介绍如何使用Python编写非递归的汉诺塔算法:步骤1: 定义一个Stack类首先,我们需要定义一个Stack类来模拟栈的行为。
在Python中,可以使用列表来实现这个类。
我们可以使用列表的append()方法将元素添加到栈顶,使用pop()方法从栈顶取出元素,使用isEmpty()方法检查栈是否为空,以及使用size()方法获取栈的大小。
下面是Stack类的代码实现:class Stack:def __init__(self):self.items = []def isEmpty(self):return len(self.items) == 0def push(self, item):self.items.append(item)def pop(self):return self.items.pop()def size(self):return len(self.items)步骤2: 定义一个非递归的汉诺塔函数接下来,我们需要定义一个非递归的汉诺塔函数。
该函数的输入参数包括圆盘的数量、起始柱子、目标柱子和辅助柱子。
函数的实现思路如下:- 首先,将所有的圆盘按照倒序从起始柱子压入起始栈。
采用递归和非递归方法求解hannol问题

采用递归和非递归方法求解hannol问题汉诺塔问题是数学中的经典问题之一,也被认为是计算机科学中的经典问题。
它的解法可以使用递归或非递归的方法。
在本文中,我们将介绍并比较这两种解法。
汉诺塔问题的描述是:有三根柱子,A、B、C,初始时,A柱子上有n个盘子,这些盘子从小到大按顺序堆叠在一起。
现在需要将这n 个盘子从A柱子移动到C柱子上,期间可以借助B柱子。
移动盘子有以下几个规则:1.每次只能移动一个盘子;2.盘子只能从大盘子移到小盘子上;3.在移动过程中,可以借助柱子进行中转。
接下来,我们将先介绍递归解法。
递归解法:对于n个盘子,我们可以将问题分解为以下三个步骤:1.将n-1个盘子从A柱子移动到B柱子;2.将第n个盘子从A柱子移动到C柱子;3.将n-1个盘子从B柱子移动到C柱子。
递归解法的代码如下:```pythondef hanoi(n, A, B, C):if n == 1:print("Move disk %d from %s to %s" % (n, A, C)) else:hanoi(n-1, A, C, B)print("Move disk %d from %s to %s" % (n, A, C)) hanoi(n-1, B, A, C)```在这个递归函数中,n表示盘子的数量,A、B、C表示三根柱子。
当n为1时,直接将第一个盘子从A柱子移动到C柱子;否则,先将n-1个盘子从A柱子移动到B柱子,然后将第n个盘子从A柱子移动到C柱子,最后将n-1个盘子从B柱子移动到C柱子。
递归的过程中,会不断地将问题分解为子问题,直到子问题规模减小到1。
下面是一个具体的例子,假设有3个盘子,初始时都在A柱子上:```pythonhanoi(3, 'A', 'B', 'C')```输出结果为:```Move disk 1 from A to CMove disk 2 from A to BMove disk 1 from C to BMove disk 3 from A to CMove disk 1 from B to AMove disk 2 from B to CMove disk 1 from A to C```如上所示,递归解法将问题分解为子问题,然后逐步解决子问题,最后得到整体的解。
汉诺塔问题非递归算法c语言

汉诺塔问题非递归算法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;}```在这个非递归算法中,我们使用了一个栈来模拟递归的过程。
四柱汉诺塔非递归算法实现

,:
Mo v e ( A, C ) ; h a n o i 3 ( n - 1 , B , A , C ) ;
}
l
三柱 汉诺塔 非 递归算 法 分析 : 先不 考虑 盘子 个数 , 我们 对 h a n o i 3 ( A , B , C ) 进 行 一 次 递 归展 开 , 如图 1 , 得 到一 棵 二 叉树 , 对图 1 二 叉 树
图 3 三 柱 汉 诺 四 次 递 归过 程
本文 考虑 带 四柱 的汉诺 塔 问题 , 四柱 汉诺 塔 问题 和三 柱 汉诺 塔 问题 的惟 一 区别就 是 增加 了一 个 柱,目 标 是用 最少 的移 动 次 数将 A柱 上 的 n个盘 子 通 过 B 柱和 C柱移 到 D柱 上 。 虽然 四柱 汉诺 塔只 L L = 柱汉 诺 塔 多一 个柱, 但 是解 决它 的难 度远 大 于三柱 汉诺 塔 。 对 于盘 数 为 n的 四柱 汉诺 塔 问题 , 可 以递 归地 定
h a n o i 3 ( r , A, C , D ) ;
பைடு நூலகம்
9 6 . 福建电脑 I 2 0 1 3 年 第u期
煎…堡… … 曼… 照
UJ } AN C0 M pt J T嚣随
h a n o i 4 ( n — r , B , A, C , D ) ;
B , B 一> D , D 一> A进 行循 环 。 v o i d o u t p u t ( i n t p r e s e n t _ l e v e l , i n t p o s i t i o n , i n t r ) { / 参数 分 别为 : 当前层 号 , 在 本层 的序 号 , 层 号 所
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
汉诺塔递归与非递归算法研究作者1,作者2,作者33(陕西师范大学计算机科学学院,陕西西安 710062)摘要: 摘要内容(包括目的、方法、结果和结论四要素) 摘要又称概要,内容提要.摘要是以提供文献内容梗概为目的,不加评论和补充解释,简明,确切地记述文献重要内容的短文.其基本要素包括研究目的,方法,结果和结论.具体地讲就是研究工作的主要对象和范围,采用的手段和方法,得出的结果和重要的结论,有时也包括具有情报价值的其它重要的信息.摘要应具有独立性和自明性,并且拥有与文献同等量的主要信息,即不阅读全文,就能获得必要的信息.关键词:关键词1; 关键词2;关键词3;……(一般可选3~8个关键词,用中文表示,不用英文Title如:XIN Ming-ming , XIN Ming(1.Dept. of ****, University, City Province Zip C ode, China;2.Dept. of ****, University, City Province Zip C ode, China;3.Dept. of ****, University, City Province Zip C ode, China)Abstract: abstract(第三人称叙述,尽量使用简单句;介绍作者工作(目的、方法、结果)用过去时,简述作者结论用一般现在时)Key words: keyword1;keyword2; keyword3;……(与中文关键词对应,字母小写(缩略词除外));正文部分用小5号宋体字,分两栏排,其中图表宽度不超过8cm.。
设置为A4页面1 引言(一级标题四号黑体加粗)这个问题当时老和尚和众僧们,经过计算后,预言当所有的盘子都从基柱A移到基座B上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
其实,不管这个传说的可信度有多大,如果考虑把64个盘子,由一个塔柱上移到另一根塔柱上,并且始终保持上小下大的顺序。
假设有n个盘子,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。
此后不难证明f(n)=2n-1。
n=64时,f(64)= 2^64-1=18446744073709551615假如每秒钟一次,共需多长时间呢?一年大约有 31536926 秒,计算表明移完这些金片需要5800多亿年,比地球寿命还要长,事实上,世界、梵塔、庙宇和众生都早已经灰飞烟灭。
对传统的汉诺塔问题,目前还有不少的学者继续研究它的非递归解法,本文通过对递归算法的研究…….提示:(1)可以定义问题的规模n,如盘子的数量;(2)塔柱的数量(目前有部分理论可以支撑,不妨用计算机实现)分析规模的变化与算法的复杂度比较。
(3)可以对经典的汉诺塔问题条件放松、加宽,如在经典的汉诺塔问题中大盘只能在小盘下面,放松其他条件可以定义相邻两个盘子必须满足大盘只能在小盘下面。
其它盘子不作要求。
2 算法设计2.1 汉诺塔递归算法描述(二级标题小五黑体加粗)用人类的大脑直接去解3,4或5个盘子的汉诺塔问题还可以,但是随着盘子个数的增多,问题的规模变的越来越大。
这样的问题就难以完成,更不用说吧问题抽象成循环的机器操作。
所以类似的问题可用递归算法来求解。
下面n个盘的汉诺塔问题可用如下递归方法实现。
如果n=1,则将圆盘从A直接移动到B。
如果n=2,则:(1)将A上的n-1(等于1)个圆盘移到C上;(2)再将A上的一个圆盘移到B上;(3)最后将C上的n-1(等于1)个圆盘移到B上。
如果n=3,则:A)将A上的n-1(等于2)个圆盘移到C(借助于B),步骤如下:(1)将A上的n-2(等于1)个圆盘移到B上。
(2)将A上的一个圆盘移到C。
(3)将B上的n-2(等于1)个圆盘移到C。
B)将A上的一个圆盘移到B。
C)将C上的n-1(等于2)个圆盘移到B(借助A),步骤如下:(1)将C上的n-2(等于1)个圆盘移到A。
(2)将C上的一个盘子移到B。
(3)将A上的n-2(等于1)个圆盘移到B。
到此,完成了三个圆盘的移动过程。
从上面分析可以看出,当n大于等于2时,移动的过程可分解为三个步骤:第一步把A上的n-1个圆盘移到C上;第二步把A上的一个圆盘移到B上;第三步把C上的n-1个圆盘移到B上;其中第一步和第三步是类同的。
算法如下:(伪码描述、自然语言描述、流程图)Main1: { int n ;2: Input(n);3: Hanoi(n,”A”,”B”,”C”) ; }4: Hanoi(n,char a,char b,char c)5: { if (n>0)6: { hanoi ( n - 1, a, c, b) ;7: printf “( %d %a - > %c \n”, n , a, c) ;8: hanoi ( n - 1,b, a, c) ;}}递归算法结构清晰,可读性强,而且很容易用数学归纳法证明算法的正确性,然而它的运行效率较低,它的时间复杂度主要在程序嵌套调用所用的时间。
T(N)=2T(N-1)+1,容易计算出T(N)=2N-1.若在程序中消除递归调用,使其转化为非递归调用算法。
通常,消除递归采用一个用户定义的栈来模拟系统的递归调用工作栈,从而达到递归改为非递归算法的目的。
2.2 汉诺塔非递归算法描述2.2.1非递归1:遍历二叉树搜索解空间(三级标题小五楷体)通过定义MAXSTACK栈,可将递归算法转化为非递归调用算法。
具体程序如下:#define MAXSTACK 100 /* 栈的最大深度*/int N = 3; /* N阶问题/*int c = 1; /* 一个全局变量,表示目前移动的步数*/struct hanoi { /* 存储汉诺塔的结构,包括盘的数目和三个盘的名称*/int n; char a, b, c;};struct hanoi p[MAXSTACK];void move(char a, int n, char c) /* 移动函数,表示把某个盘从某根针移动到另一根针*/{ printf("%d. Move disk %d from %c to %c\n", c++, n, a, c);} void push(struct hanoi *p, int top, char a, char b, char c,int n){p[top+1].n = n - 1;p[top+1].a = a;p[top+1].b = b;p[top+1].c = c; }void unreverse_hanoi(struct hanoi *p) /*汉诺塔的非递归算法*/ { int top = 0;while (top >= 0) {while (p[top].n > 1) { /* 向左走到尽头*/push(p, top, p[top].a, p[top].c, p[top].b, p[top].n);top++; }if (p[top].n == 1) { /* 叶子结点*/move(p[top].a, 1, p[top].b);top--; }if (top >= 0) { /* 向右走一步*/move(p[top].a, p[top].n, p[top].c);top--;push(p, top, p[top+1].b, p[top+1].a, p[top+1].c, p[top+1].n);top++; } }}int main(void){ printf("unreverse program:n");c = 1; p[0].n = N;p[0].a = 'a', p[0].b = 'b', p[0].c = 'c';unreverse_hanoi(p);return 0;}2.2.2非递归2:优化遍历二叉树搜索解空间如:从汉诺塔的递归算法中可知,当盘子的个数大于2 时,汉诺塔的移动过程分为3步,第一步将n-1个盘从A 移到C;第二步将第n盘从A 移到B;第三步将n-1个盘从C移到B。
如果把移动过程看作是二叉树的中序遍历,则可用二叉树与汉诺塔移动过程建立一个映射[2,3]。
如图2所示,三阶盘数,所对应的移动过程共有3!=6种移动方法。
即:A→B ,A→C, B→C, B→A, C→A, C→B 6种移动方法.图 2 移动过程的映射在构造解空间树的时候,遵循由初始塔→目标塔,分解为两部分:初始塔→和中转塔→目标塔。
如图3所示构造n 阶汉诺塔问题的解空间树与对应的解。
依次类推一直到达叶节点生成满二叉树。
最后对生成的二叉树中序遍历,每搜索一个结点,对应的输出它的映射值,例如:搜索到0号结点,则输出A →B, 搜索到3号结点,则输出B →A, 搜索到5号结点,则输出C →B.依次类推直到解空间树中所有结点搜索完成,算法结束。
1. from A →B2. from A →C3. from B →C4. from A →B5. from C →A6. from C →B7. from A →B012054A →BA →CC→BC→AA→B(a)(b)B →CA→B图3 3阶汉诺塔与所对应的解空间树下面给出它的中序遍历算法。
将二叉树严格按照左子树在左,右子树在右画,中序遍历的结果应该是结点从左到右的一个排列。
由于它是满二叉树,整个输出过程是,先输出最下层的一个结点,然后,输出上层中第一个左子树能包含该结点的结点,然后,再输出下层的下一个结点,再输出上层中第一个左子树能包含该结点的结点,直到下层的结点全部输出完为止。
用一维数level_position [] 存储某一层已输出的结点序号。
由于该二叉树是满二叉树,上层第i 个结点的左孩子一定是下层的第2i-1个结点,右孩子一定是下层的第2i 个结点。
这样,判断下层结点是否是上层结点的右孩子,只要判断上下层结点在其本层的编号是否构成2倍关系即可,整个算法程序实现如下:void output (int present_level, int position, int n) //参数分别为:当前层号,在本层的序号,总层数 { int val;val= (position-1) %3;if (present_level%2= =1) val=val+3; //如果是奇数层,其值为3, 4, 5switch (val){case 0: printf ("%d from A--->B\n" ,n -present_level+1) ; break; case 1: printf (" %d from B--->C\n" ,n-present_level+1) ; break; case 2: printf (" % d from C--->A\n" ,n -present_level+1);break; case 3:printf ("% d from A --->C\n" ,n -present_level+1) ; break; case 4: printf (" %d from C--->B\n" ,n-present_level+1) ; break; case 5:printf ("% d from B--->A\n" ,n-present_level+1); break;}} main (){ int level_position [100] ; //某层的已输出的结点序号 int n,i,sample_nub,total_sample;//最后一层已输个数、总个数 printf (" input n=") ; //盘的数量 scanf (" %d" ,&n) ; printf (" \n") ;sample_nub=0;total_sample=1;for (i=1;i<n;i++) total_sample*=2; //最底层总样点数 for (i=0;i<=n;i++) level_position [i] =0; i=n;level_position [i] ++;output (i,level_position [n] ,n) ;//输出第i 层某一序号的结点 sample_nub++;while (sample_nub<total_sample){ while (level_position [i] ==2*level_position [i-1] ) i--; //寻找把该结点作为左子树的祖先结点 level_position [i-1] ++; output (i-1,level_position [i-1] ,n) ; i=n;level_position [i] ++;output (i,level_position [n] ,n) ; sample_nub++;} }3 算法分析定理1.算法1是可终止的。