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

第一根上面套着 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.hqwc.cn/news/610796.html

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

相关文章

Linux:Redis7.2.4的源码包部署(2)

本章使用的是centos9进行部署 1.获取rpm安装包 Index of /releases/ (redis.io)https://download.redis.io/releases/这个网站有历史的版本&#xff0c;我这里使用的是最新版7.2.4进行安装 点击即可进行下载 方进Linux中&#xff0c;如果你的Linux中可以直接使用wget去下载 2…

自动驾驶硬回灌和软回灌

目录 前言 一、硬回灌 实时性 直接影响行为 高度依赖传感器 二、软回灌 非实时性 系统优化和改进 数据驱动的学习 三、区别与联系 四、自动驾驶中硬回灌和软回灌代表性方法 硬回灌 软回灌 前言 自动驾驶系统中&#xff0c;"硬回灌"和"软回灌"…

【洛谷 P4017】最大食物链计数 题解(深度优先搜索+动态规划+邻接表+记忆化搜索+剪枝)

最大食物链计数 题目背景 你知道食物链吗&#xff1f;Delia 生物考试的时候&#xff0c;数食物链条数的题目全都错了&#xff0c;因为她总是重复数了几条或漏掉了几条。于是她来就来求助你&#xff0c;然而你也不会啊&#xff01;写一个程序来帮帮她吧。 题目描述 给你一个…

uname -a --输出和系统本身相关-内核版本、硬件架构32位/64位

uname命令&#xff1a;主要用于输出一组操作系统的信息 包含内核的版本、硬件架构是32位还是64位 输入--help后看看效果&#xff0c;一目了然 首先输出完整信息&#xff1a; 我们再依次来输出一下&#xff1a; 最后&#xff0c;我们只需要记住uname命令可以输出和系统本身相关…

Python数据结构与算法——算法(贪心算法、动态规划

贪心算法 介绍&#xff1a;贪心算法又称贪婪算法&#xff0c;是指在对问题求解时&#xff0c;总是做出在当前看来是最好的选择。也就是说&#xff0c;不从整体最优上加以考虑&#xff0c;它所做出的是在某种意义上的局部最优解。 贪心算法并不保证会得到最优解&#xff0c;但…

LangChain-18 Caching 将回答内容进行缓存 可在内存中或数据库中持久化缓存

背景描述 可以将问答的内容缓存起来&#xff0c;如果是相同的问题&#xff0c;那么将会直接把答案返回去&#xff0c;可以节约费用和计算。 安装依赖 pip install -qU langchain-core langchain-openai编写代码 我们可以通过 InMemoryCache 进行内存缓存 或者 SQLiteCache …

电脑无法开机?原因分析与解决方案

电脑无法开机是一种常见的问题&#xff0c;可能会给用户带来诸多困扰。无法启动可能是由于硬件故障、软件问题或者其他未知原因引起的。在本文中&#xff0c;我们将介绍三种常见的方法来解决电脑无法开机的问题&#xff0c;以帮助用户尽快恢复正常使用。 方法1&#xff1a;检查…

spfa算法(java代码)

题目: 851. spfa求最短路 - AcWing题库 输入样例: 3 3 1 2 5 2 3 -3 1 3 4 输出样例: 2 分析&#xff1a; 先去定义一个class 类似于c里面的pair 里面有两个变量x, y 因为后面需要用优先队列来处理最短路问题需要指出比较x还是y 因此我们让这个pair类实现 Comparable 接口 实…

HarmonyOS实战开发-WebSocket的使用。

介绍 本示例展示了WebSocket的使用&#xff0c;包括客户端与服务端的连接和断开以及客户端数据的接收和发送。 WebSocket连接&#xff1a;使用WebSocket建立服务器与客户端的双向连接&#xff0c;需要先通过createWebSocket方法创建WebSocket对象&#xff0c;然后通过connect…

数据应用OneID:ID-Mapping Spark GraphX实现

前言 说明 以用户实体为例&#xff0c;ID 类型包含 user_id 和 device_id。当然还有其他类型id。不同id可以获取到的阶段、生命周期均不相同。 device_id 生命周期通常指的是一个设备从首次被识别到不再活跃的整个时间段。 user_id是用户登录之后系统分配的唯一标识&#xff…

Ubuntu (Linux系统) 下载安装 Qt 环境

在官网http://download.qt.io/archive/qt/ 下载安装包&#xff0c;默认linux平台下提供的安装包以run后缀结尾 也可以选择其它地址下载 Qt官网下载地址&#xff1a;https://download.qt.io&#xff1b; 国内镜像下载地址&#xff1a;https://mirrors.cloud.tencent.com/qt/ 。建…

【牛客SQL快速入门】SQL基础(三)

一、条件函数 IF 条件函数 IF函数是最常用到的条件函数&#xff0c;写法为 if(xn,a,b)&#xff0c;xn代表判断条件&#xff0c;如果xn时&#xff0c;那么结果返回a&#xff0c;否则返回b。 -- 把非北京大学的用户统一归为其他大学 Select device_id,if(university ‘北京大…