汉诺塔c语言源程序步骤,汉诺塔问题的算法分析及C语言演示程序的实现

摘要:该文对经典的“汉诺塔”问题进行了详细的分析,并用C语言实现。通过问题的具体实现,使学习者了解问题的全过程,推广到一般。

关键词:汉诺塔;递归;C语言

中图分类号:TP301.6文献标识码:A文章编号:1009-3044(2010)09-2130-02

Algorithm Analysis and C Realization of Hanio Issue

BAI Hui-bo1,GAO Rui-ping2

(1.Qinhuangdao Branch of Daqing Petroleum Institute, Qinhuangdao 066004, China;2.Hebei Normal University of Science and Technology, Qinhuangdao 06600, China)

Abstract: This text carries on detailed analysis about classical Hanio issue and provides realization of algorithm in C.Through concrete realization of the problem,can make learners observe the whole course which solves this issue and Extend to the general.

Key words: hanio; recursive; the C programming language

1 问题描述

汉诺塔是一个经典的数学问题,其具体描述如下:有三根相邻的塔子,标号为A,B,C,A塔子上从下到上按金字塔状叠放着n个不同大小的圆盘,现在把所有盘子借助于A,B,C三个塔子一个一个移动到塔子C上,并且每次移动在同一根塔子上都不能出现大盘子在小盘子上方.根据问题描述得到以下规则:

1)圆盘必须一个一个的移动;

2)大的圆盘必须在小圆盘的下方或单一圆盘;

3)满足规则2)的序列可以出现在A,B,C任意一根塔子上。

C语言演示程序规则:

1)输入一个盘子的个数n(时间可接受范围内的值0

2)用C语言演示盘子在塔A,B,C间的移动全过程。

2 算法分析

题目实现的是设计一个盘子移动的方案,使得A塔上的所有盘子借助于B塔按照原来的次序移动到C塔上,并且给出完整的最佳的盘子移动的方案。

从实际的具体的盘子的移动过程来分析,找出问题内在的规律。当n=1时,问题比较简单,只要将塔A上的编号为1盘子直接移动到塔C即可;当n>1时,需利用塔B作为辅助塔,若能设法将压在编号为n的盘子之上的n-1个盘子从塔A(依据移动规则)移至塔B上,则可将编号为n的盘子从塔A移至塔C,然后再将塔B上的n-1个盘子(依据移动规则)移至塔C;经分析可知,在移动的过程中, 将始终会出现这样的状态情况: (n-1)个盘子将会以从下到上、从大到小的次序叠置在B塔上,这时,A塔上第n个盘子就能被轻而易举叠放到C塔上; 接着, 我们再把B塔上的共(n-1)个盘子移动到C塔上, 问题好像已经解决。

但B塔上(n-1)个盘子怎么移动到C塔上呢?同样, 利用塔C作为辅助塔, 将会出现这样的状态情况:(n-2)个盘子将会以从上到下、从小到大的次序叠置在A塔上,这时,B塔上第(n-2)个盘子就能被轻而易举放到C塔上;接着,把A塔上的共(n-2)个盘子移动到C塔上。

这明显是一个递归的过程,不断深入,不断细小化,最终,将到达仅有一个盘的情形,这时, 递归也就终止了,问题也得到了解决。通过以上分析,递归的出口是当n=1时,能直接得到解。现在,严格按照递归算法来解决问题。先定义递归方法Hanio(int n,zarray * A, zarray *B, zarray *C),按如下步骤进行解题(设初始盘子个数为N):若A塔上仅仅只有一个盘子(n=1), 则直接从A移动到C,问题完全解决。若A塔上有一个以上的盘子(n>1),则需要考虑以下三个步骤。

第一步: 把(n-1)个盘子从A塔经过移动, 叠放到C塔上。在不违反规则情况下,所有(n-1)个盘子不能作为一个整体一起移动,而是要符合要求地从一个塔移到另一个塔上。用Hanio(n-1,A,C,B)调用递归方法,注意:这里是借助于C塔,将(n-1)个盘子从A塔移动到B塔, A是源塔, B是目标塔。

第二步: 将剩下的第n个盘子(也就是最底下的一个)直接从A塔叠放到空着的C塔上。

第三步: 用第一步的方法,再次将B塔上的所有盘子叠放到C塔上。同样,这一步实际上也是由一系列更小的符合规则的移动盘子的操作组成的。用Hanio(n-1,B,A,C)调用递归方法, 注意:这里是借助于A塔,将(n-1)个盘子从B塔移动到C塔,B是源塔,C是目标塔。这个算法达到了预期的目标,即在C塔上按正确的次序叠放了所有的圆形盘子。

3 算法实现

定义结构体plate表示盘子:typedef struct

{ int x,y,xsize,ysize;/*盘子通过绘制椭圆实现,x,y,xsize,ysize确定椭圆的大小*/

int No;/*盘子的编号,编号为0的表示塔柱,大于零的是盘子*/

}plate;

定义一个堆栈zarray来表示塔:typedef struct

{plate p[INIT_SIZE];

int top;/*栈顶*/

int x,y,xof,yof; /*塔的绘制视区*/

}zarray;

用zarray的三个变量A、B、C分别表示三个塔,初始盘子在A塔,设置屏幕绘制区域并相对与绘制区域分别绘制A、B、C三塔、盘子,并在相应盘子的位置标明其编号(编号和盘子一起移动)调用hanoi()函数,并在move()函数中源塔和目标塔的盘子进行绘制。

程序的主要函数由:initZarray(),setLongth(),getplate(),pushplate(),popplate(), outNo(),toDraw(),toDrawZhu(),getn(),hanoi(),move()等组成。

initZarray()负责塔A,B,C数据的初始化, pushplate()负责将盘子压入目标塔中,并对新压入的盘子进行绘制,popplate()负责从源塔取下一个盘子,并对源塔进行重新绘制。

1)函数main()的算法

函数main()的算法如图1,程序执行用户根据提示输入合法的n值,根据得到的n值初始化塔A,B,C和n个盘子的大小,设置绘图视区在屏幕上绘制塔A,B,C和盘子,调用hanoi()函数。

2)函数hanoi()的算法

函数hanoi()的算法如图1,当程序第一被调用时,源塔A有n个盘子,将塔C作为辅助塔,调用move()函数将源塔A上的n-1个盘子移至塔B上,将源塔A上的编号为n的盘子移到目标塔C,完成将最大盘子移至目标塔C,接下来,将塔B作为源塔有n-1个盘子,塔A作为辅助塔递归调用,每次都将源塔上的最大盘子移至目标塔,直到递归结束。

3)函数move()的算法

函数move()的算法如图2,函数的作用就是调用popplate()函数,将源塔出栈重绘,再将出栈的盘子p调用pushplate()函数压入目标塔,重新绘制。popplate()函数和pushplate()见图2。

4 结束语

本文深入分析了用递归实现汉诺塔的问题,并用图形仿真程序显示的盘子的移动过程,对汉诺塔的本质进行了新的剖析,对数据结构的教学有一定的好处。

参考文献:

[1] 严蔚敏,吴伟民.数据结构[M].北京:清华大学出版社,1996.

[2] 王强如.C语言绘图与计算机仿真技术[M].北京:北京航空航天大学出版社,1995.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281580.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring security xml配置详解

security 3.x <?xml version"1.0" encoding"UTF-8"?> <beans:beans xmlns"http://www.springframework.org/schema/security" xmlns:beans"http://www.springframework.org/schema/beans" xmlns:xsi"http://www…

【Redis源码分析】Redis命令处理生命周期

运营研发团队 李乐 前言 本文主要讲解服务器处理客户端命令请求的整个流程&#xff0c;包括服务器启动监听&#xff0c;接收命令请求并解析&#xff0c;执行命令请求&#xff0c;返回命令回复等&#xff0c;这也是本文的主题“命令处理的生命周期”。 Redis服务器作为典型的事件…

博鳌直击 | 区块链在互联网金融中扮演怎样的角色?

雷锋网3月24日报道&#xff0c;今日&#xff08;3月24日&#xff09;&#xff0c;第16届博鳌亚洲论坛2017年年会在海南继续进行中。据雷锋网了解&#xff0c;在今日下午的数字货币与区块链分论坛上&#xff0c;中国银行前行长、中国互联网金融协会区块链工作组组长李礼辉讲述了…

GDB调试qemu-kvm

GDB调试qemu-kvm 前面几篇博文都是记录一些kvm相关包编译安装及使用&#xff0c;但都没深入去代码看看。看源码在配合上相关原理才能更好的理解kvm。但qemu-kvm的代码量很多&#xff0c;对我来讲直接看源码收获甚少&#xff0c;所以找了个调试工具——GDB来配合阅读代码。接下来…

c语言编译错误 原文,C语言常见错误与警告

C语言常见错误与警告C语言常见错误与警告C语言常见错误&#xff1a;1 invalid type argument of ‘->’ (have ‘struct qstr_xid_element’)这种错误一般是没有理解C中“->”与“.”用法的不同&#xff0c;“->”是指向结构体指针获取结构体的成员变量时所用&#xf…

力争营收渠道多样化,Line 向自拍应用 Snow 投资 4500 万美元

今年&#xff0c;在科技公司 IPO 市场不景气的情况下&#xff0c;日本通信应用 Line顺利进行了 IPO &#xff0c;目前正在寻求多样化发展。今天, Line 宣布向自拍应用 Snow 投资 4500 万美元(500 亿韩元)。本次交易之后&#xff0c;Line 将获得 Snow 25% 的股权。 Snow 常被称为…

用.NET设计一个假装黑客的屏幕保护程序

本文主要介绍屏幕保护程序的一些相关知识&#xff0c;以及其在安全方面的用途&#xff0c;同时介绍了如何使用 .NET 开发一款屏幕保护程序&#xff0c;并对核心功能做了介绍&#xff0c;案例代码开源&#xff1a;https://github.com/sangyuxiaowu/HackerScreenSaver背景前几天在…

【IntelliJ】IntelliJ IDEA常用设置及快捷键以及自定义Live templates

IntelliJ IDEA是一款非常优秀的JAVA编辑器&#xff0c;初学都可会对其中的一些做法感到很别扭&#xff0c;刚开始用的时候我也感到很不习惯&#xff0c;在参考了网上一些文章后在这里把我的一些经验写出来&#xff0c;希望初学者能快速适应它&#xff0c;不久你就会感觉到编程是…

复习Javascript专题(一):基本概念部分

一、数据类型 基本类型&#xff1a;Null Boolean String Undefined Number(NB SUN)引用类型&#xff1a;Array Function Object类型判断&#xff1a;typeof 返回结果"undefined"&#xff08;未定义&#xff09; "boolean"(布尔值) "st…

c语言时钟报告,C语言图形时钟课程设计实验报告

C语言图形时钟课程设计实验报告 目录1.系统功能要求。2. 数据结构设计及说明。3.程序结构(画流程图) 。4.各模块的功能。5.试验结果(包括输入数据和输出结果) 。6.体会。7.参考文献。8.附录&#xff1a;程序清单及源程序。 系统功能要求&#xff1a;在屏幕上显示一个图形时钟…

微软发布 2023 财年第一季度财报:营收达 501 亿美元,同比增长 11%

北京时间 2022 年 10 月 26 日——微软发布 2023 财年第一季度财报。财报显示&#xff0c;截止到 2022 年 9 月 30 日&#xff1a;营收达到 501 亿美元&#xff0c;增长 11%&#xff08;按固定汇率计算增长 16%&#xff09;运营收入为 215 亿美元&#xff0c;增长 6%&#xff0…

《图解CSS3:核心技术与案例实战》——1.3节渐进增强

本节书摘来自华章社区《图解CSS3&#xff1a;核心技术与案例实战》一书中的第1章&#xff0c;第1.3节渐进增强&#xff0c;作者 大漠&#xff0c;更多章节内容可以访问云栖社区“华章社区”公众号查看 1.3 渐进增强第一次听到“渐进增强”&#xff08;Progressive Enhancement…

阿里云云主机搭建网站攻略 - 云翼计划

阿里云服务器&#xff08;云主机&#xff09;搭建网站攻略 - 云翼计划 提示&#xff1a;此搭建攻略为2017版本&#xff0c;阿里云未跟新前。 最新搭建攻略请前往 Amaya丶夜雨博客 / 最新个人博客 https://www.amayaliu.cn 支持一下哦&#xff0c;谢谢。&#xff08;9.5一…

用c语言递归函数做扫雷,【C语言基础学习---扫雷游戏】(包含普通版+递归炼狱版)...

/*******************///以下是源文件game.c内容/*******************/#include"game.h"//初始化棋盘的实现void InitBoard(char board[ROWS][COLS], int rows, int cols, char set){int i 0;int j 0;for (i 0; i < rows; i){for (j 0; j < cols; j){board…

记一次 .NET 某医疗器械 程序崩溃分析

一&#xff1a;背景 1.讲故事前段时间有位朋友在微信上找到我&#xff0c;说他的程序偶发性崩溃&#xff0c;让我帮忙看下怎么回事&#xff0c;上面给的压力比较大&#xff0c;对于这种偶发性崩溃&#xff0c;比较好的办法就是利用 AEDebug 在程序崩溃的时候自动抽一管血出来&a…

1251: 字母图形 [水题]

1251: 字母图形 [水题] 时间限制: 1 Sec 内存限制: 128 MB提交: 140 解决: 61 统计题目描述 利用字母可以组成一些美丽的图形&#xff0c;下面给出了一个例子&#xff1a; ABCDEFG BABCDEF CBABCDE DCBABCD EDCBABC 这是一个5行7列的图形&#xff0c;请找出这个图形的规律&…

c语言 三角形三边abc,C语言代码输入abc三个数,求一这3个数为边长的三角形面积...

2011-01-04 回答#include #include #include #include #include int main(){float a 0.0;float b 0.0;float c 0.0;float s 0.0;double area 0.0;while(true){printf("input your date(a,b,c):");scanf("%f%f%f",&a,&b,&c);if(!isdigit((…

shell脚本中向hive动态分区插入数据

在hive上建表与普通分区表创建方法一样&#xff1b; 1 CREATE TABLE dwa_m_user_association_circle(2 device_number string, 3 oppo_number string, 4 prov_id_oppo string, 5 area_id_oppo string, 6 dealer_oppo string, 7 short_call_nums bigint, 8 long3…

WPF效果第二百零二篇之TreeView带连接线

前面文章中分享了TreeView支持多选;然而在项目上使用时,领导觉得不满意:体现不了真正的从属关系;既然领导都发话了;那就开整就行了;今天就再来个带有连接线的TreeView效果:1、来看看TreeViewItem的Template:2、展开和收缩动画:3、参考资料https://www.codeproject.com/tips/673…

ObjectTive C语言语法,[译]理解 Objective-C 运行时(下篇)

本文来自网易云社区作者&#xff1a;宋申易所以到底 objc_msgSend 发生了什么&#xff1f;很多事情。看一下这段代码&#xff1a;[self printMessageWithString:"Hello World!"];这实际上被编译器翻译成&#xff1a;objc_msgSend(self, selector(printMessageWithStr…