第 3 章 栈和队列(汉诺塔问题递归解法)

1. 背景说明

假设有 3 个分别命名为 X、Y 和 Z 的塔座,在塔座 X 上插有 n 个直径大小各不相同、依小到大编号为 1, 2,…,n 的圆盘。

现要求将 X 轴上的 n 个圆盘移至塔座 Z 上并仍按同样顺序叠排,圆盘移动时必须遵循下列规则:
(1) 每次只能移动一个圆盘;
(2) 圆盘可以插在 X、Y 和 Z 中的任一塔座上;
(3) 任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。

2. 示例代码

1)hanoi.h

/* 汉诺塔定义头文件 */#ifndef HANOI_H
#define HANOI_H#define N 4				/* 初始汉诺塔层数 */
#define SIZE 3			/* 塔基个数 */typedef struct {int **plates;int high[3];
} Tower;void Init(int n, Tower *T);void DestroyHanoi(Tower *T);void PrintGraph(char t1, int n, char t2, Tower *T);/* 算法 3.5, 将塔座 x 上按直径由小到大且自上而下编号为 1 至 n 的 n 个圆盘按规则搬到塔座 z 上。y 可用作辅助塔座 */
void Hanoi(int n, char x, char y, char z, Tower *T, int *step);#endif // !HANOI_H

2) hanoi.c

/* 汉诺塔实现源文件 */#include "hanoi.h"
#include <stdlib.h>
#include <stdio.h>void Init(int n, Tower *T)
{/* Apply for a memory to storage the pointer of int */T->plates = (int **)malloc(SIZE * sizeof(int *));/* Apply for a memory to storage the information of the blocks */for (int i = 0; i < SIZE; ++i) {T->plates[i] = (int*)malloc(n * sizeof(int));}/* Initial the plate information */T->high[0] = n;T->high[1] = 0;T->high[2] = 0;for (int i = 0; i < n; ++i) {T->plates[0][i] = n - i;T->plates[1][i] = 0;T->plates[2][i] = 0;}
}void DestroyHanoi(Tower *T)
{for (int i = 0; i < SIZE; ++i) {free(T->plates[i]);}free(T->plates);
}/* Show move n th block from plate t1 to plate t2 */
void PrintGraph(char t1, int n, char t2, Tower *T)
{/* Check the parameters */if ((t1 == t2) && (t1 != '\0')) {printf("Error: Can not move block for the same plate to the same plate.\n");return;}/* Move from */if (t1 == 'x') {T->plates[0][T->high[0] - 1] = 0;--T->high[0];}else if (t1 == 'y') {T->plates[1][T->high[1] - 1] = 0;--T->high[1];}else if (t1 == 'z') {T->plates[2][T->high[2] - 1] = 0;--T->high[2];}/* Move to */if (t2 == 'x') {T->plates[0][T->high[0]] = n;++T->high[0];}else if (t2 == 'y') {T->plates[1][T->high[1]] = n;++T->high[1];}else if (t2 == 'z') {T->plates[2][T->high[2]] = n;++T->high[2];}/* Initialize the block string graphic */char **s = (char **)malloc((N + 2) * sizeof(char *));for (int i = 0, j; i < N + 2; ++i) {s[i] = (char *)malloc((N + 1) * sizeof(char));for (j = 0; j < i; ++j) {if (i == N + 1) {s[i][j] = '-';}else {s[i][j] = '*';}}if (i == N + 1) {s[i][j - 1] = '\0';}else {s[i][j] = '\0';}}// Eg: N = 2// s[0][0] = '\0'// s[1][0] = '*', s[1][1] = '\0'// s[2][0] = '*', s[2][1] = '*', s[2][2] = '\0'// s[3][0] = '-', s[3][1] = '-', s[3][2] = '-', s[3][2] = '\0'for (int i = N - 1; i >= 0; --i) {printf("%-*s|%-*s|%-*s\n", N, s[T->plates[0][i]], N, s[T->plates[1][i]], N, s[T->plates[2][i]]);}printf("%-*s+%-*s+%-*s\n", N, s[N + 1], N, s[N + 1], N, s[N + 1]);printf("%-*s%-*s%-*s\n", N + 2, "x", N + 2, "y", N + 2, "z");   /* use "" not the '' */for (int i = 0; i < N + 2; ++i) {free(s[i]);}free(s);
}static void Move(char x, int n, char z, Tower *T, int *step)
{/* If use (*step)++, do not forget add() cause the priority of the ++ is higher than *You can also not add the() instead use ++*step, no problem but bad reading */++(*step);printf("The step %2d: Move %dth block from %c to %c\n\n", *step, n, x, z);PrintGraph(x, n, z, T);printf("\n");
}/* 算法 3.5, 将塔座 x 上按直径由小到大且自上而下编号为 1 至 n 的 n 个圆盘按规则搬到塔座 z 上。y 可用作辅助塔座 */
void Hanoi(int n, char x, char y, char z, Tower *T, int *step)
{if (n == 1) {Move(x, 1, z, T, step);}else {Hanoi(n - 1, x, z, y, T, step);Move(x, n, z, T, step);Hanoi(n - 1, y, x, z, T, step);}
}

3) main.c

/* 汉诺塔主函数源文件 */
/* Note: Consider use stack to storage the information of the hanoi tower */#include "hanoi.h"
#include <stdio.h>int main(void)
{char x = 'x', y = 'y', z = 'z';printf("Initialize the %d layers hanoi tower:\n\n", N);Tower T = { 0 };Init(N, &T);PrintGraph('\0', 0, '\0', &T);printf("\n");int step = 0;Hanoi(N, x, y, z, &T, &step);DestroyHanoi(&T);return 0;
}

3. 输出示例

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

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

相关文章

平板触控笔哪款好用?好用的第三方apple pencil

而对于那些把ipad当做学习工具的人而言&#xff0c;苹果Pencil就成了必备品。但因为苹果Pencil太贵了&#xff0c;不少的学生们买不起。因此&#xff0c;最佳的选择还是平替电容笔&#xff0c;今天在这里整理了一些高性价比的电容笔&#xff01; 一、挑选电容笔的要点&#xf…

软件设计师学习笔记9-进程调度

目录 1. PV操作 1.1进程的同步与互斥 1.1.1互斥 1.1.2同步 1.2 PV操作 1.2.1信号量 1.2.2 PV操作的概念 2.信号量与PV操作 2.1 PV操作与互斥模型 2.2 PV操作与同步模型 2.3 互斥与同步模型结合 3.前趋图与PV操作 1. PV操作 1.1进程的同步与互斥 1.1.1互斥 互斥&…

【已解决】pycharm 突然每次点击都开新页面,关不掉怎么办?

今天在 pycharm 中写代码&#xff0c;突然发现&#xff0c;新开的文件不再原来的页面上&#xff0c;而是新增了页面&#xff0c;导致整个屏幕全都是新开的页面&#xff0c;最难受的是&#xff0c;关不掉&#xff01; 无奈&#xff0c;我只能关闭 pycharm&#xff0c;重新双击…

谷歌Chrome庆祝15周年,推出全新设计!了解最新信息!

谷歌浏览器本月将满15岁&#xff0c;为了纪念这一时刻&#xff0c;它正在进行改造和升级。 这一点意义重大&#xff0c;因为Chrome在全球有数十亿人使用&#xff0c;因此谷歌所做的每一项改变都会对互联网以及这些人与互联网的互动方式产生巨大影响。即使你不使用Chrome或不关…

输运方程的推导

1 概述 对于流场中守恒的物理量&#xff0c;均可采用输运方程&#xff08;transport equation&#xff09;进行描述其随时间变化和在空间的分布规律。输运方程的通用形式为&#xff1a; 输运方程描述了流动过程中的物理量守恒&#xff0c;其包括瞬态&#xff08;transient&…

uView实现全屏选项卡

// 直接复制粘贴即可使用 <template><view><view class"tabsBox"><u-tabs-swiper ref"uTabs" :list"list":current"current"change"tabsChange":is-scroll"false"></u-tabs-swiper&g…

在VR全景中嵌入3D模型有哪些优势?

现阶段&#xff0c;很多商企都会引入VR全景展示来宣传推广自己的产品、服务以及环境&#xff0c;但是环境展示凸显的沉浸式体验只是 VR全景一部分的价值所在&#xff0c;商企使用VR全景还有一个优势就是互动性&#xff0c;通过丰富多样的互动性&#xff0c;让用户同VR场景中的物…

vscode html使用less和快速获取标签less结构

扩展插件里面搜索 css tree 插件 下载 使用方法 选择你要生成的标签结构然后按CTRLshiftp 第一次需要在输入框输入 get 然后选择 Generate CSS tree less结构就出现在这个里面直接复制到自己的less文件里面就可以使用了 在html里面使用less 下载 Easy LESS 插件 自己创建…

spring---第一篇

系列文章目录 文章目录 系列文章目录一、如何实现一个IOC容器二、spring是什么?一、如何实现一个IOC容器 1、配置文件配置包扫描路径 2、递归包扫描获取.class文件 3、反射、确定需要交给IOC管理的类 4、对需要注入的类进行依赖注入 配置文件中指定需要扫描的包路径 定义一些…

Android之 SVG绘制

一 SVG介绍 1.1 SVG&#xff08;Scalable Vector Graphics&#xff09;是可缩放矢量图形的缩写&#xff0c;它是一种图形格式&#xff0c;其中形状在XML中指定&#xff0c; 而XML又由SVG查看器呈现。 1.2 SVG可以区别于位图&#xff0c;放大可以做到不模糊&#xff0c;可以做…

【实战】React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(总结展望篇)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…

springboot 集成dubbo

上一篇我们一起认识了Dubbo与RPC&#xff0c;今天我们就来一起学习如何使用Dubbo&#xff0c;并将Dubbo集成到Spring Boot的项目中。我们来看下今天要使用到的软件及版本&#xff1a; 软件 版本 说明 Java 11 Spring Boot 2.7.13 Spring Boot 3.0版本开始&#xff0c;最…

【C#】泛型

【C#】泛型 泛型是什么 泛型是将类型作为参数传递给类、结构、接口和方法&#xff0c;这些参数相当于类型占位符。当我们定义类或方法时使用占位符代替变量类型&#xff0c;真正使用时再具体指定数据类型&#xff0c;以此来达到代码重用目的。 泛型特点 提高代码重用性一定…

去掉Egde浏览器选择文本弹出的搜索小按钮

去掉Egde浏览器选择文本弹出的搜索小按钮 小按钮 去掉&#xff1a;在设置中找到选择文本时的微型菜单&#xff0c;关闭【选择文本时显示迷你菜单】选项

Java LinkedList

简介 链表&#xff08;Linked list&#xff09;是一种常见的基础数据结构&#xff0c;是一种线性表&#xff0c;但是并不会按线性的顺序存储数据&#xff0c;而是在每一个节点里存到下一个节点的地址。 链表可分为单向链表和双向链表。 在Java程序设计语言中&#xff0c;所有…

JVM中JAVA对象和数组内存布局

对象 数组 在Java中&#xff0c;所有的对象都是一种特殊的数组&#xff0c;它们的元素可以是基本数据类型、其他对象引用或者其他任何类型。Java对象和数组的内存布局包含以下部分&#xff1a; 1.对象头&#xff08;Object Header&#xff09; 每个Java对象都有一个对象头&am…

软件提示vcruntime140_1.dll丢失的解决方法,以及丢失的原因总结

在运行某些程序时&#xff0c;可能会出现“vcruntime140_1.dll 丢失”的错误提示。这是因为 vcruntime140_1.dll 是 Visual C Redistributable 的一部分&#xff0c;它通常被安装在 Windows 操作系统上。如果该文件丢失或无法找到&#xff0c;可能会导致程序无法正常运行。在我…

LLMs之Baichuan 2:《Baichuan 2: Open Large-scale Language Models》翻译与解读

LLMs之Baichuan 2&#xff1a;《Baichuan 2: Open Large-scale Language Models》翻译与解读 导读&#xff1a;2023年9月6日&#xff0c;百川智能重磅发布Baichuan 2。科技论文主要介绍了Baichuan 2&#xff0c;一个开源的大规模语言模型&#xff0c;以及其在多个领域的性能表现…

js案例:选字游戏

目录 效果预览图 游戏规则 整体思路 完整代码 html部分 js部分 效果预览图 游戏规则 1.游戏时间为30s&#xff0c;30s倒计时结束弹出游戏结束和对应的游戏分数。 2.根据中间大字的颜色&#xff0c;点击下面对应的文字。 大字的颜色 点击的文字&#xff08;列如&#…