linux学习:栈(汉诺塔游戏)

news2024/11/26 12:42:50

第一根上面套着 64 个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地 把它们一个个地从这根棒搬到另一根棒上,规定可利用中间的一根棒作为帮助,但每次只能 搬一个,而且大的不能放在小的上面。

每次只能拿最上面的一个,然后放的时候也必须放到最上面,这 个逻辑其实就是栈。再要解决这个问题,可以将这个问题“递归化”:假设有 n 个汉诺塔 在 A 号柱子上,那么解题的步骤是:

  • 第①步:将 A 上面的 n-1 个汉诺塔先搬到 C 上。
  • 第②步:直接将 A 最底下的那块汉诺塔出栈,然后直接在 B 上压栈。
  • 第③步:再把那 n-1个汉诺塔从 C 搬到 B 上。

1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <stdbool.h>
5
6 struct node // 链式栈节点
7 {
8     int data;
9     struct node *next;
10 };
11
12 struct linked_stack // 链式栈的管理结构体
13 {
14     struct node *top; // 栈顶元素指针
15     int size; // 当前栈元素总数
16 };
17
18 struct linked_stack *s1, *s2, *s3; // 定义成全局变量是为了方便打印
19
20 bool stack_empty(struct linked_stack *s) // 判断栈是否为空
21 {
22     return s->size == 0;
23 }
24
25 struct node *new_node(int data) // 创建一个新的节点
26 {
27     struct node *new = malloc(sizeof(struct node));
28     if(new != NULL)
29     {
30         new->data = data;
31         new->next = NULL;
32     }
33     return new;
34 }
35 // 将新节点 new 压入栈 s 中
36 bool push(struct linked_stack *s, struct node *new)
37 {
38     if(new == NULL)
39         return false;
40
41     new->next = s->top;
42     s->top = new;
43     s->size++;
44
45     return true;
46 }
47 // 从栈 s 中取出栈顶元素
48 bool pop(struct linked_stack *s, struct node **p)
49 {
50     if(stack_empty(s))
51         return false;
52
53     *p = s->top;
54     s->top = s->top->next;
55     (*p)->next = NULL;
56     s->size--;
57
58     return true;
59 }
60
61 void show(struct linked_stack *s1, 
62     struct linked_stack *s2, 
63     struct linked_stack *s3) // 纵向同时显示三个链栈数据
64 {
65     int maxlen, len;
66
67     maxlen = s1->size > s2->size ? s1->size : s2->size;
68     maxlen = maxlen > s3->size ? maxlen : s3->size;
69     len = maxlen;
70
71     struct node *tmp1 = s1->top;
72     struct node *tmp2 = s2->top;
73     struct node *tmp3 = s3->top;
74
75     int i;
76     for(i=0; i<maxlen; i++)
77     {
78         if(tmp1 != NULL && len <= s1->size)
79         {
80             printf("%d", tmp1->data);
81             tmp1 = tmp1->next;
82         }
83         printf("\t");
84
85         if(tmp2 != NULL && len <= s2->size)
86         {
87             printf("%d", tmp2->data);
88             tmp2 = tmp2->next;
89         }
90         printf("\t");
91
92         if(tmp3 != NULL && len <= s3->size)
93         {
94             printf("%d", tmp3->data);
95             tmp3 = tmp3->next;
96         }
97         printf("\n");
98
99         len--;
100     }
101     printf("s1\ts2\ts3\n-----------------\n");
102 }
103
104 void hanoi(int n, struct linked_stack *ss1, 
105     struct linked_stack *ss2, 
106     struct linked_stack *ss3)
107 {
108     if(n <= 0)
109         return;
110
111     struct node *tmp;
112
113     hanoi(n-1, ss1, ss3, ss2); // 第①步:将 n-1 个汉诺塔从 s1 移到 s3
114     getchar();
115     show(s1, s2, s3);
116     pop(ss1, &tmp);// 第②步:将最底层汉诺塔从 s1 移动到 s2
117     push(ss2, tmp);
118     hanoi(n-1, ss3, ss2, ss1); // 第③步:将 n-1 个汉诺塔从 s3 移到 s2
119 }
120 // 初始化一个空的链栈
121 struct linked_stack *init_stack(void)
122 {
123     struct linked_stack *s;
124     s = malloc(sizeof(struct linked_stack)); // 申请链栈管理结构体
125
126     if(s != NULL)
127     {
128         s->top = NULL;
129         s->size = 0;
130     }
131     return s;
132 }
133
134 int main(void)
135 {
136     printf("how many hanois ? ");
137     int hanois;
138     scanf("%d", &hanois);
139
140     s1 = init_stack(); // 初始化三个链栈,用来表示三根金刚石柱子
141     s2 = init_stack();
142     s3 = init_stack();
143
144     int i;
145     for(i=0; i<hanois; i++) // 在第一个栈中压入 n 个数,代表汉诺塔
146     {
147         struct node *new = new_node(hanois-i);
148         push(s1, new);
149     }
150
151     hanoi(hanois, s1, s2, s3); // 使用递归算法移动这些汉诺塔
152     show(s1, s2, s3); // 显示移动之后的汉诺塔形状
153
154     return 0;
155 }

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

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

相关文章

【vue】v-model 双向数据绑定

:value&#xff1a;单向数据绑定v-model&#xff1a;双向数据绑定 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

Maven创建项目

目录 1.创建项目 2.从Maven Repository: Search/Browse/Explore (mvnrepository.com)链接&#xff0c;下载API 3.1.0 3.在main文件内创建webapp文件夹&#xff0c;再webapp文件夹内创建WEB-INF文件夹&#xff0c;在WEB-INF文件夹内创建web.xml 4.网络编程 5.打包 6.部署 …

Leetcode二十三题:合并K个升序链表【22/1000 python】

“合并K个升序链表”&#xff0c;这是一道中等难度的题目&#xff0c;经常出现在编程面试中。以下是该问题的详细描述、解题步骤、不同算法的比较、代码示例及其分析。 问题描述 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中…

vue快速入门(十九)使用动态类绑定实现TabBar动态样式

注释很详细&#xff0c;直接上代码 上一篇 新增内容 vue绑定动态样式根据点击事件获取当前点击部分序号 源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"width…

开源模型应用落地-chatglm3-6b-function call-入门篇(六)

一、前言 每个模型都有自己的限制&#xff0c;有些情况下它们无法满足复杂的业务需求。但是&#xff0c;可以通过一个外置函数的方式&#xff0c;例如&#xff1a;"Function Call"&#xff0c;让开发者能够更加灵活地利用大型语言模型&#xff0c;帮助开发者在特定场…

《QT实用小工具·十九》回车跳转到不同的编辑框

1、概述 源码放在文章末尾 该项目实现通过回车键让光标从一个编辑框跳转到另一个编辑框&#xff0c;下面是demo演示&#xff1a; 项目部分代码如下&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget>namespace Ui { class Widget; }class Widget : p…

【Nacos】Nacos最新版的安装、配置过程记录和踩坑分享

Nacos是什么&#xff1f;有什么功能&#xff1f;大家可以自行联网&#xff08;推荐 https://cn.bing.com/&#xff09;搜索&#xff0c;这里就不做介绍了。 简单的看了下官网&#xff0c;安装最新版的Nacos&#xff08;v2.3.2&#xff09;需要使用到JDK&#xff08;1.8.0&…

JS原生DOM操作 - 获得元素/网页大小/元素宽高

文章目录 获得元素的方法获取页面元素位置宽高概念方法获得网页/元素宽高clientHeight和clientWidth&#xff1a;scrollHeight和scrollWidth&#xff1a;window.innerWidth&#xff1a;element.style.width&#xff1a; offsetXXX 获得网页元素的宽高和相对父元素位置&#xff…

关于运行阿里云直播Demo pub get 报的错

flutter --version dart --version 如何使用Flutter框架推流_音视频终端 SDK(Apsara Video SDK)-阿里云帮助中心MediaBox音视频SDK下载指南_音视频终端 SDK(Apsara Video SDK)-阿里云帮助中心 终端输入 dart pub --trace get --no-precompile 打印详细报错信息 详细咨…

⭐Unity 里调用弹出电脑系统文件选择窗 (选择图片/文件)

今天遇到的需求要从Uinty里调用选择程序外的图片&#xff0c;类似手机环境下拿图库的照片一样。 效果如下: 话不多说 直接上代码&#xff01; 1.编辑器模式下 using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using Syst…

Android Studio开发学习(六)———TableLayout(表格布局)、FrameLayout(帧布局)

目录 前言 一、Tablelayout &#xff08;一&#xff09;Tablelayout的相关简介 &#xff08;二&#xff09;TableLayout使用方法 1. 当TableLayout下面写控件、则控件占据一行的大小。(自适应一行&#xff0c;不留空白) 2.多个组件占据一行&#xff0c;则配合TableRow实现…

RocketMQ之Topic和Tag最佳实践

一、Topic是什么&#xff1f;它的作用&#xff1f; Topic即主题&#xff0c;是消息队列中用于对消息进行分类和组织的一种机制&#xff0c;它有以下三种作用&#xff1a; 标识消息分类&#xff1a;RocketMQ的主题用于对消息进行分类和组织。通过为不同类型的消息分配不同的主题…

FireProx:一款功能强大的AWS API网关管理与IP地址轮换代理工具

关于FireProx FireProx是一款功能强大的AWS API网关安全管理工具&#xff0c;该工具可以帮助广大研究人员创建实现唯一IP地址轮换的实时HTTP转发代理。 在发送网络请求或进行网络交互时&#xff0c;实现源IP地址轮换是一个非常复杂的过程&#xff0c;虽然社区中也有相关的工具…

ShardingSphere再回首

概念&#xff1a; 连接&#xff1a;通过协议 方言及库存储的适配&#xff0c;连接数据和应用&#xff0c;关注多模数据苦之间的合作 增量&#xff1a;抓取库入口流量题提供重定向&#xff0c; 流量变形(加密脱敏)/鉴权/治理(熔断限流)/分析等 可插拔&#xff1a;微内核 DDL:cr…

皮具5G智能制造工厂数字孪生可视化平台,推进企业数字化转型

皮具5G智能制造工厂数字孪生可视化平台&#xff0c;推进企业数字化转型。随着信息技术的快速发展&#xff0c;数字化转型已成为企业提升竞争力、实现可持续发展的关键路径。皮具行业&#xff0c;作为一个传统的手工制造业&#xff0c;正面临着巨大的市场变革和技术挑战。如何在…

(Java)数据结构——图(第十节)AOE网以及关键路径

目录 前言 AOE网 AOE网的两个性质&#xff1a; AOE网的五个时间 事件的最早发生时间Ve[k] 活动的最早开始时间E[i] 事件的最迟发生时间Vl[k] 活动的最晚开始时间L[i] 活动的时间余量 关于关键路径的缩短 代码实现思路 前言 本博客是博主用于复习数据结构以及算法的博…

蓝桥杯备赛刷题——css

新鲜的蔬菜 这题需要使用grid 我不会 去学一下 一.什么是grid Grid 布局与 Flex 布局有一定的相似性&#xff0c;都可以指定容器内部多个项目的位置。但是&#xff0c;它们也存在重大区别。 Flex 布局是轴线布局&#xff0c;只能指定"项目"针对轴线的位置&#…

(非技术) 基因遗传相关知识学习笔记

目录 一、基因遗传名词解释 二、什么叫显性遗传和隐性遗传&#xff1f; 三、如何确定遗传性质呢&#xff1f;是显性还是隐性&#xff1f; 四、常规例子1&#xff1a; 五、常规例子2&#xff1a; 六、实际案例&#xff1a; 七、思考题&#xff1a; 八、参考&#xff1a; …

【Redis深度解析】揭秘Cluster(集群):原理、机制与实战优化

Redis Cluster是Redis官方提供的分布式解决方案&#xff0c;通过数据分片与节点间通信机制&#xff0c;实现了水平扩展、高可用与数据容灾。本文将深入剖析Redis Cluster的工作原理、核心机制&#xff0c;并结合实战经验分享优化策略&#xff0c;为您打造坚实可靠的Redis分布式…

Qt QProcess详解

1.简介 QProcess提供了在 Qt 应用程序中启动外部程序的方法。通过QProcess&#xff0c;你可以启动一个进程&#xff0c;与它通信&#xff08;发送输入和读取输出&#xff09;&#xff0c;检查它的状态&#xff0c;以及等待它完成。这个类在执行系统命令、运行其他程序或脚本时…