啊哈!算法-第2章-栈、队列、链表

啊哈!算法-第2章-栈、队列、链表

  • 第1节 解密qq号——队列
  • 第2节 解密回文——栈
  • 第3节 纸牌游戏——小猫钓鱼
  • 第4节 链表
  • 第5节 模拟链表

第1节 解密qq号——队列

  1. 新学期开始了,小哈是小哼的新同桌(小哈是个大帅哥哦~),小哼向小哈询问 QQ 号, 小哈当然不会直接告诉小哼啦,原因嘛你懂的。所以小哈给了小哼一串加密过的数字,同时 小哈也告诉了小哼解密规则。规则是这样的:首先将第 1 个数删除,紧接着将第 2 个数放到 这串数的末尾,再将第 3 个数删除并将第 4 个数放到这串数的末尾,再将第 5 个数删除… 直到剩下最后一个数,将最后一个数也删除。按照刚才删除的顺序,把这些删除的数连在一 起就是小哈的 QQ 啦。现在你来帮帮小哼吧。小哈给小哼加密过的一串数是“5 3 0 3 9 3 0 1”。
密文删除的数字移到最后的数字QQ号
53039301535
03930130350
93013393509
01333015090
33313350903
31331509033
3135090333
1150903331

解密的第一步是将第一个数删除,你可以想一下如何在数组中删除一个数呢。最简单的 方法是将所有后面的数都往前面挪动一位,将前面的数覆盖。就好比我们在排队买票,最前 面的人买好离开了,后面所有的人就需要全部向前面走一步,补上之前的空位,但是这样的 做法很耗费时间。
在这里,我将引入两个整型变量 head 和 tail。head 用来记录队列的队首(即第一位), tail 用来记录队列的队尾(即最后一位)的下一个位置。你可能会问:为什么 tail 不直接记 录队尾,却要记录队尾的下一个位置呢?这是因为当队列中只剩下一个元素时,队首和队尾重合会带来一些麻烦。我们这里规定队首和队尾重合时,队列为空。
现在有 n 个数,n 个数全部放入队列之后 head = 0;tail = strlen(QQ);此时 head 和 tail 之间的数就是
目前队列中“有效”的数。如果要删除一个数的话,就将 head++就 OK 了,这样仍然可以保 持 head 和 tail 之间的数为目前队列中“有效”的数。这样做虽然浪费了一个空间,却节省了 大量的时间,这是非常划算的。新增加一个数也很简单,把需要增加的数放到队尾即 q[tail] 之后再 tail++就 OK 啦。

  1. 在队首删除一个数的操作是 head++;
  2. 在队尾增加一个数(假设这个数是 x)的操作是 q[tail] = x; tail++;
  3. 以上操作重复执行若干次,直到head < tail结束即可
#include<iostream>using namespace std;const int maxn = 100;
int head, tail;
char QQ[maxn];
int main(){cin >> QQ;head = 0; // head指向密文的开始位置,tail指向密文的结束位置+1tail = strlen(QQ);// 当队列不为空的时候执行循环while (head < tail){// 打印队首,并将队首出队cout << QQ[head++];//先将新队首的数添加到队尾,再将队首出队QQ[tail++] = QQ[head++];}return 0;
}

队列是一种特 殊的线性结构,它只允许在队列的首部(head)进行删除操作,这称为“出队”,而在队列 的尾部(tail)进行插入操作,这称为“入队”。
当队列中没有元素时(即 head==tail),称为 空队列。
“先进先出”(First In First Out,FIFO)原则。

struct queue{int data[100]; // 队列的主体,用来存储内容int head; // 队首int tail; // 队尾
};

上面定义了一个结构体类型,我们通常将其放在 main 函数的外面,请注意结构体的定 义末尾有个;号。struct 是结构体的关键字,queue 是我们为这个结构体起的名字。这个结构 体有三个成员分别是:整型数组 data、整型 head 和整型 tail。这样我们就可以把这三个部分 放在一起作为一个整体来对待。你可以这么理解:我们定义了一个新的数据类型,这个新类 型非常强大,用这个新类型定义出的每一个变量可以同时存储一个整型数组和两个整数。
在这里插入图片描述

有了新的结构体类型,如何定义结构体变量呢?很简单,这与我们之前定义变量的方式 是一样的,具体做法如下。

struct queue QQ;

请注意 struct queue 需要整体使用,不能直接写 queue q;。这样我们就定义了一个结构体 变量 q。这个结构体变量就可以满足队列的所有操作了。那又该如何访问结构体变量的内部 成员呢?可以使用.号,它叫做成员运算符或者点号运算符,如下:

QQ.head = 1;
QQ.tail = 1;
scanf("%d", &QQ.data[q.tail]);

下面这段代码就是使用结构体来实现的队列操作。

#include<iostream>using namespace std;struct queue{string data; // 队列主体,用来存储内容int head, tail; // 队首和队尾
};int main(){queue QQ;cin >> QQ.data;// 初始化队列QQ.head = 0;QQ.tail = QQ.data.length();// //当队列不为空的时候执行循环while (QQ.head <= QQ.tail){cout << QQ.data[QQ.head]; //打印队首QQ.head++; // 将队首出队QQ.data[QQ.tail] = QQ.data[QQ.head];  // 先将新队首的数添加到队尾QQ.head++; // 再将队首出队QQ.tail++;}return 0;
}

第2节 解密回文——栈

栈是后进先出的数据 结构。它限定为只能在一端进行插入和删除操作。比如说有一个小桶,小桶的直 径只能放一个小球,我们现在小桶内依次放入 2、1、3 号小球。假如你现在需要拿出 2 号小球, 那就必须先将 3 号小球拿出,再拿出 1 号小球,最后才能将 2 号小球拿出来。在刚才取小球的 过程中,我们最先放进去的小球最后才能拿出来,最后放进去的小球却可以最先拿出来。

在这里插入图片描述

栈究竟有哪些作用呢?我们来看一个例子。“xyzyx”是一个回文字符串,所谓回文字符 串就是指正读反读均相同的字符序列,如“席主席”、“记书记”、“aha”和“ahaha”均是回 文,但“ahah”不是回文。通过栈这个数据结构我们将很容易判断一个字符串是否为回文。
首先我们需要读取这行字符串,并求出这个字符串的长度。

char arr[100];
int len;
cin >> arr;
len = strlen(arr);

如果一个字符串是回文的话,那么它必须是中间对称的,我们需要求中点,即:

mid = len / 2 + 1;

接下来就轮到栈出场了。
我们先将 mid 之前的字符全部入栈。因为这里的栈是用来存储字符的,所以这里用来实 现栈的数组类型是字符数组即 char s[101];,初始化栈很简单,top = 0;就可以了。入栈的操作 是top++; s[top] = x(;假设需要入栈的字符暂存在字符变量x中),其实可以简写为arr[++top] = x;。
现在我们就来将 mid 之前的字符依次全部入栈。

for (int i = 0; i <= mid; i++){s[++top] = arr[i];

接下来进入判断回文的关键步骤。将当前栈中的字符依次出栈,看看是否能与 mid 之后 的字符一一匹配,如果都能匹配则说明这个字符串是回文字符串,否则这个字符串就不是回 文字符串。

for(i = mid+1; i <= len - 1; i++){if (a[i] != s[top]){break; }top--; 
}
if(top == 0)printf("YES");
elseprintf("NO");

最后如果 top 的值为 0,就说明栈内所有的字符都被一一匹配了,那么这个字符串就是 回文字符串。完整的代码如下。

#include<iostream>using namespace std;
const int maxn = 200;
int main(){char arr[maxn], s[maxn];int len, mid, next, top;cin >> arr; // 读入一行字符串len = strlen(arr); // 求字符串的长度mid = len / 2 - 1; // 求字符串的终点top = 0; // 栈的初始化// 将mid前的字符一次入栈for (int i = 0; i <= mid; i++){s[++top] = arr[i];}// 判断字符串的长度是奇数还是偶数,并找出需要进行字符匹配的起始下标if (len % 2 == 0){next = mid + 1;}else{next = mid + 2;}// 开始匹配for (int i = next; i < len; i++){if (arr[i] != s[top]){break;}top--;}// 如果top的值为0,则说明栈内所有的字符都被一一匹配了if (top == 0){cout << "YES";}else{cout << "NO";}return 0;
}

第3节 纸牌游戏——小猫钓鱼

星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓 鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的 第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌 的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人 手中的牌全部出完时,游戏结束,对手获胜。

假如游戏开始时,小哼手中有 6 张牌,顺序为 2 4 1 2 5 6,小哈手中也有 6 张牌,顺序 为 3 1 3 5 6 4,最终谁会获胜呢?现在你可以拿出纸牌来试一试。接下来请你写一个程序来 自动判断谁将获胜。这里我们做一个约定,小哼和小哈手中牌的牌面只有 1~9。
在这里插入图片描述
我们先来分析一下这个游戏有哪几种操作。小哼有两种操作,分别是出牌和赢牌。这恰 好对应队列的两个操作,出牌就是出队,赢牌就是入队。小哈的操作和小哼是一样的。而桌 子就是一个栈,每打出一张牌放到桌上就相当于入栈。当有人赢牌的时候,依次将牌从桌上 拿走,这就相当于出栈。那如何解决赢牌的问题呢?赢牌的规则是:如果某人打出的牌与桌 上的某张牌相同,即可将两张牌以及中间所夹的牌全部取走。那如何知道桌上已经有哪些牌 了呢?最简单的方法就是枚举桌上的每一张牌,当然也有更好的办法我们待会再说。OK, 小结一下,我们需要两个队列、一个栈来模拟整个游戏。

首先我们先来创建一个结构体用来实现队列,如下。

struct queue{int data[1000];int head;int tail;
}

上面代码中 head 用来存储队头,tail 用来存储队尾。数组 data 用来存储队列中的元素, 数组 data 的大小我预设为 1000,其实应该设置得更大一些,以防数组越界。当然对于本题 的数据来说 1000 已经足够了。
再创建一个结构体用来实现栈,如下。

struct stack{int data[10];int top;
};

其中 top 用来存储栈顶,数组 data 用来存储栈中的元素,大小设置为 10。因为只有 9 种不同的牌面,所以桌上最多可能有 9 张牌,因此数组大小设置为 10 就够了。提示一下: 为什么不设置为 9 呢?因为 C ++数组下标是从 0 开始的。

接下来我们需要定义两个队列变量 q1 和 q2。q1 用来模拟小哼手中的牌,q2 用来模拟小 哈手中的牌。定义一个栈变量 s 用来模拟桌上的牌。

struct queue heng, ha;
struct stack table;

接下来来初始化一下队列和栈。

// 初始化队列heng, ha为空,此时两人手中都还没有牌
heng.head = 1;
heng.tail = 1;
ha.head = 1;
ha.tail = 1;
// 初始化栈table为空,最开始的时候桌上也没有牌
table.top = 0;

未完待续… …

第4节 链表

第5节 模拟链表

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

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

相关文章

uniapp微信小程序解决open-type获取用户头像,返回临时路径问题!

解决 open-type 为 chooseAvatar&#xff0c;返回临时路径问题 文章目录 解决 open-type 为 chooseAvatar&#xff0c;返回临时路径问题效果图Demo获取头像回调数据结构效果图解决方式上传到服务器转base64 基于微信小程序获取头像昵称规则调整后&#xff0c;当小程序需要让用户…

高通Android 12/13 设置和获取ADB状态

/*** 设置ADB状态** param isEnable*/public void setADB(boolean isEnable) {Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ADB_ENABLED, isEnable ? 1 : 0);}/*** 获取ADB状态** return*/public boolean getADB() {return Settings.Global.getIn…

虚拟化技术[3]之网络虚拟化

网络虚拟化 网络虚拟化简介核心层网络虚拟化接入层网络虚拟化虚拟机网络虚拟化案例: VMware网络虚拟化技术虚拟网络接口卡虚拟交换机vSwitch分布式交换机端口组VLAN 网络虚拟化简介 传统的数据中心&#xff1a;服务器之间操作系统和上层软件异构、接口与数据格式不统一&#x…

基于hive的酒店价格数据可视化分析系统设计和实现

摘要 本文基于Django框架和Hive技术&#xff0c;设计和实现了一种酒店价格数据可视化分析系 统&#xff0c;旨在为酒店管理者提供直观、清晰的数据洞察和决策支持。在研究中&#xff0c;首先深入分 析了酒店价格数据可视化分析系统的背景和意义&#xff0c;认识到对于酒店行…

3.Redis之Redis的环境搭建redis客户端介绍

1.版本的选取 安装 Redis&#xff1a;Redis 5 系列~~ 在 Linux 中进行安装~~ Redis 官方是不支持 Windows 版本的~~ 微软维护了一个 Windows 版本的 Redis 分支 Centos和Ubuntu.Docker 2.如何进行安装&#xff1f;&#xff1f;&#xff1f; 1.ubuntu 2.centos yum instal…

arcgisPro将一个图层的要素复制到另一个图层

1、打开两个图层&#xff0c;如下&#xff0c;其中一个图层中有两个要素&#xff0c;需要将其中一个要素复制到另一个图层中&#xff0c;展示如下&#xff1a; 2、选中待复制要素&#xff0c;点击复制按钮&#xff0c;如下&#xff1a; 3、下拉粘贴按钮列表&#xff0c;选择【选…

Ubuntu22.04虚拟机设置静态IP

虚拟机设置静态IP 按下电脑的 “win”键&#xff0c;在弹出的输入框中输入“控制面板”&#xff0c;选中控制面板 1.选择 “网络和Internet” 2.选择 “网络和共享中心” 3.选择 “更改适配器设置” 4.选择 “VMnet8”&#xff0c;双击打开 5.选择 “属性” 找到 “Internet …

【idea】idea2024最新版本下载_安装_破解

1、下载 下载地址&#xff1a;下载 IntelliJ IDEA – 领先的 Java 和 Kotlin IDE 下载完成&#xff1a; idea破解脚本下载链接&#xff1a;https://pan.baidu.com/s/1L5qq26cRABw8XuEn_CngKQ 提取码&#xff1a;6666 下载完成&#xff1a; 2、安装 1、双击idea的安装包&…

《计算机网络微课堂》1-6 计算机体系结构

常见的计算机网络体系结构 从本节课开始&#xff0c;我们要用 4 次课的时间来介绍有关计算机网络体系结构的知识&#xff0c;具体包含以下内容&#xff1a; 一&#xff0c;常见的计算机网络体系结构二&#xff0c;计算机网络体系结构分层的必要性三&#xff0c;计算机网络体系…

给我瞅瞅呀

专业 流程&#xff08;一条龙服务&#xff09; 需求沟通-需求分析-产品架构-ue原型-ui设计-产品研发-产品测试-产品交付-产品运维 保障 1、按需定制&#xff0c;签订功能清单&#xff0c;根据功能报价 2、价格透明&#xff0c;签订合同保障&#xff0c;保障客户合法权益 3、源…

监控员工电脑屏幕的五大软件(电脑监控软件大盘点)

监控员工电脑屏幕是企业为了提升工作效率、确保信息安全和合规性而采取的一种常见做法。以下是五款在2024年备受推荐的员工电脑屏幕监控软件&#xff0c;每款软件都具有其独特的功能和优势&#xff1a; 1. 域智盾 域智盾是一款全面的终端管理系统&#xff0c;集成了实时屏幕监…

动态代理,反射,注解的复习笔记

1.动态代理的作用 动态代理最主要的用途就是在各种框架中&#xff0c;很方便的在运行期间生成代理类&#xff0c;通过代理类就可以完成AOP、过滤器、拦截器等操作 &#xff08;注&#xff1a;代理就是被代理者没有能力或者不愿意去完成某件事情&#xff0c;需要找个人代替自己…

02.爬虫---HTTP基本原理

02.HTTP基本原理 1.URI 和 URL 的区别2.HTTP 和 HTTPS 的区别3.请求过程 1.URI 和 URL 的区别 URL&#xff08;Uniform Resource Locator&#xff09;即-统一资源定位符 URL是用来定位和访问互联网上资源的独特标识&#xff0c;它包括了资源的位置&#xff08;如IP地址或域名&a…

移动硬盘难题:不显示容量与无法访问的解决策略

在使用移动硬盘的过程中&#xff0c;有时会遇到一些棘手的问题&#xff0c;比如移动硬盘不显示容量且无法访问。这种情况让人十分头疼&#xff0c;因为它不仅影响了数据的正常使用&#xff0c;还可能导致重要数据的丢失。接下来&#xff0c;我们就来详细探讨一下这个问题及其解…

CentOS 7安装/卸载Grafana

说明&#xff1a;本文介绍CentOS 7操作系统如何安装/卸载Grafana&#xff1b; 安装 Step1&#xff1a;下载rpm文件 敲下面的命令&#xff0c;下载grafana的rpm文件 wget https://dl.grafana.com/oss/release/grafana-7.3.7-1.x86_64.rpmStep2&#xff1a;安装grafana 敲下…

使用xxl-job-executor-go 接入xxl-job实现定时任务调度

定时任务是软件开发中很常见的一种处理业务的机制&#xff0c;xxl-job是近些年比较火的定时任务调用组件&#xff0c;其采用java 实现&#xff0c;是一个高可用&#xff0c;分布式调用的组件&#xff0c;还支持多种定时任务有关的特性&#xff0c;不仅能轻易的用java 客户端接入…

SpringBoot高级原理详解

今日内容&#xff1a; 理解SpringBoot自动化配置源码理解SpringBoot健康监控 1 SpringBoot自动化配置原理 01-SpringBoot2高级-starter依赖管理机制 目的&#xff1a;通过依赖能了解SpringBoot管理了哪些starter讲解&#xff1a; 通过依赖 spring-boot-dependencies 搜索 …

【C++】<知识点> 标准模板库STL(上)

文章目录 一、STL---string类 1. 常用构造函数 2. 常用操作 3. 字符串流处理 二、STL---容器 1. STL及基本概念 2. 顺序容器简介 3. 关联容器简介 4. 容器适配器简介 5. 常用成员函数 三、STL---迭代器 1. 普通迭代器 2. 双向、随机访问迭代器 3. 不同容器的迭代器…

数据结构:二叉树与树

一 树的基本概念&#xff1a; 1.树的形状&#xff1a; 2.树的定义&#xff1a; 树是一种非线性的数据结构&#xff0c;它是n(n > 0)个结点的有限集。当n 0时&#xff0c;称为空树。在任意一棵非空树中应满足&#xff1a; 2.1 有且仅有一个特定的称为根的结点。 2.2 当n …

k8s二进制安装与部署

目录 一、实验目的 二、实验环境 三、实验步骤 3.1 操作系统初始化配置 3.2 部署 docker引擎 3.3 部署 etcd 集群 3.3.1 在 master01 节点上操作 ​3.3.2 在 node01 节点上操作 3.3.3 在 node02 节点上操作 3.4 部署 Master 组件 3.4.1 在 mast…