数据结构03:栈、队列和数组 队习题01[C++]

  

考研笔记整理~🥝🥝

之前的博文链接在此:数据结构03:栈、队列和数组_-CSDN博客~🥝🥝

本篇作为链表的代码补充,供小伙伴们参考~🥝🥝

  • 第1版:王道书的课后习题~🧩🧩

编辑:梅头脑🌸

参考用书:王道考研《2025年 数据结构考研复习指导》


目录

🧵01 不牺牲存储单元的单链表

🧵02 队列元素逆置

🧵03 利用两个栈模拟队列

🧵04 链栈

🔚结语


🧵01 不牺牲存储单元的单链表

🧩题目

若希望循环队列中的元素都能得到利用,则需设置一个标志域 tag,并以 tag 的值为 0或1来区分队头指针 front 和队尾指针 rear 相同时的队列状态是“空”还是“满”试编写与此结构相应的入队和出队算法。

📇解题思路

虽然 入栈和出栈的指针判断均为 front == rear,但是考虑到仅入栈会导致栈满,出栈是导致栈空,因为,入栈与出栈的条件如下:

  • tag == 1(上一次为入队操作) && front == rear 时,表示栈满;
  • tag == 0(上一次为出队操作) && front == rear 时,表示栈空;

⌨️解题代码

#include <iostream>
using namespace std;const int MaxSize = 5;
typedef struct {int data[MaxSize];int front, rear;int tag;
}SeQueue;class Queue {
private:SeQueue* q;
public:Queue();~Queue();bool IsEmpty();bool IsFull();bool EnQueue(int x);bool DeQueue(int& x);
};Queue::Queue() {q = new SeQueue;q->front = q->rear = 0;q->tag = 0;
}
Queue::~Queue() {delete q;
}
bool Queue::IsEmpty() {if (q->front == q->rear && q->tag == 0) { cout << "队列为空"; return true; }else { cout << "队列不空"; return false; }
}
bool Queue::IsFull() {if (q->front == q->rear && q->tag == 1) { cout << "队列已满"; return true; }else { cout << "队列未满"; return false; }
}
bool Queue::EnQueue(int x) {if (IsFull() == true) { cout << " 入队失败" << endl; return false; }q->data[q->rear] = x;q->rear = (q->rear + 1) % MaxSize;q->tag = 1;cout << " 元素" << x << "入队成功" << endl; return true;
}
bool Queue::DeQueue(int& x) {if (IsEmpty() == true) { cout << " 出队失败" << endl; return false; }x = q->data[q->front];q->front = (q->front + 1) % MaxSize;q->tag = 0;cout << " 元素" << x << "出队成功" << endl; return true;
}int main()
{Queue q;int x;q.EnQueue(1);q.EnQueue(2);q.EnQueue(3);q.EnQueue(4);q.EnQueue(5);q.EnQueue(6); // 队列已满, 入队失败q.DeQueue(x); cout << "出队元素:" << x << endl;q.DeQueue(x); cout << "出队元素:" << x << endl;q.DeQueue(x); cout << "出队元素:" << x << endl;q.DeQueue(x); cout << "出队元素:" << x << endl;q.DeQueue(x); cout << "出队元素:" << x << endl;q.DeQueue(x); // 队列为空, 出队失败return 0;
}


🧵02 队列元素逆置

🧩题目

只是一个队列,S是一个空栈,实现将队列中的元素逆置的算法。

📇解题思路

先把队的东西导入栈,再次出栈入队时即可实现逆序存储~

⌨️解题代码

#include <iostream>
#include <queue>
#include <stack>
using namespace std;bool Reverse(queue<int>& q) {stack<int> s;// 队列q中的元素全部入栈swhile (!q.empty()) {s.push(q.front());q.pop();}// 栈s中的元素全部入队列qwhile (!s.empty()) {q.push(s.top());s.pop();}return true;
}int main() {queue<int> q;q.push(1);q.push(2);q.push(3);bool result = Reverse(q);while (!q.empty()) {cout << q.front() << " ";q.pop();}return 0;
}


🧵03 利用两个栈模拟队列

🧩题目

利用两个栈 S1 和 S2 来模拟一个队列,已知栈的4个运算定义如下:
Push(S,x);                //元素x入栈 s
Pop(S,x);                  //s出栈并将出栈的值赋给x
StackEmpty(S);        //判断栈是否为空
StackOverflow(S);    //判断栈是否满
如何利用栈的运算来实现该队列的3个运算(形参由读者根据要求自己设计)?
Engueue;                  //将元素x入队
Dequeue;                  //出队,并将出队元素存储在x中
QueueEmpty;            //判断队列是否为空

📇解题思路

入栈的时候直接进S1,但是出栈时就不能直接从S1出栈了:栈顶元素出栈,不满足队列要求;

然而,S1的元素导入S2就可以实现一个负负得正的效果,因此,出栈的时候,先把S1的元素搬入S2,然后直接从S2中出栈~

⌨️解题代码

#include <iostream>
#include <stack>
using namespace std;const int MaxSize = 5;class Queue {
private:stack<int> s1;stack<int> s2;int size;
public:Queue();~Queue();bool Enqueue(int x);bool Dequeue(int& x);bool QueueEmpty();
};Queue::Queue() {size = 0;
}
Queue::~Queue() {
}
bool Queue::Enqueue(int x) {if (size == MaxSize) {cout << "队列已满" << endl;return false;}s1.push(x);size++;cout << "元素" << x << "入队成功" << endl;return true;
}
bool Queue::Dequeue(int& x) {if (size == 0) {cout << "队列为空" << endl;return false;}// 如果s2为空, 则将s1中的元素全部转移到s2中;否则s2不为空, 元素直接出队if (s2.empty()) {while (!s1.empty()) {s2.push(s1.top());s1.pop();}}x = s2.top();s2.pop();size--;cout << "元素" << x << "出队成功" << endl;return true;
}
bool Queue::QueueEmpty() {if (size == 0) {cout << "队列为空" << endl;return true;}else {cout << "队列不空" << endl;return false;}
}int main() {Queue q;int x;q.Enqueue(1); // 栈S1:1,栈S2:空q.Enqueue(2); // 栈S1:1 2,栈S2:空q.Enqueue(3); // 栈S1:1 2 3,栈S2:空q.Dequeue(x); // 栈S1:空,栈S2: 3 2q.Enqueue(4); // 栈S1:4,栈S2:3 2q.Enqueue(5); // 栈S1:4 5,栈S2:3 2q.Enqueue(6); // 栈S1:4 5 6,栈S2:3 2q.Dequeue(x); // 栈S1:4 5 6,栈S2:3 q.Enqueue(7); // 栈S1:4 5 6 7,栈S2:3q.Enqueue(8); // 队列已满, 入队失败q.Dequeue(x); // 栈S1:4 5 6 7,栈S2:空q.Dequeue(x); // 栈S1:空,栈S2:7 6 5 4q.Dequeue(x); // 栈S1:空,栈S2:7 6 5q.Dequeue(x); // 栈S1:空,栈S2:7 6q.Dequeue(x); // 栈S1:空,栈S2:7q.Dequeue(x); // 队列为空, 出队失败return 0;
}


🧵04 链栈

🧩题目

【2019 统考真题】请设计一个队列,要求满足:①初始时队列为空;②入队时,允许增加队列占用空间;③出队后,出队元素所占用的空间可重复使用,即整个队列所占用的空间只增不减;④入队操作和出队操作的时间复杂度始终保持为0(1)。请回答:

        1)该队列是应选择链式存储结构,还是应选择顺序存储结构?
        2)画出队列的初始状态,并给出判断队空和队满的条件。
        3)画出第一个元素入队后的队列状态。
        4)给出入队操作和出队操作的基本过程。

📇算法思路

  • 链栈可以灵活增加队列占用空间,满足题目要求;而如果使用动态循环数组,平时查询和删除的时间复杂度是O(1),但是扩容的时间复杂度是O(n),这一点就不用考虑了~
  • 如果元素出队不想占用空间,那front指针直接从head后移就可以了,移动到front == rear,就是移动到末尾了~
  • emm...不过以下的代码,还是实现了删除的功能(感觉一直占用空间不删除怪怪的...)

⌨️算法代码(单链表版本)

#include <iostream>
using namespace std;typedef struct LinkNode {int data;LinkNode* next;LinkNode() : data(0), next(nullptr) {}LinkNode(int x) : data(x), next(nullptr) {}
}LinkNode;class LinkQueue {
private:LinkNode* head;LinkNode* front;LinkNode* rear;
public:LinkQueue();~LinkQueue();bool IsEmpty();bool EnQueue(int x);bool DeQueue(int& x);
};LinkQueue::LinkQueue() {head = new LinkNode;front = rear = head;
}
LinkQueue::~LinkQueue() {delete head;
}
bool LinkQueue::IsEmpty() {if (front->next == nullptr) { cout << "队列为空 "; return true; }else { cout << "队列不空 "; return false; }
}
bool LinkQueue::EnQueue(int x) {LinkNode* p = new LinkNode(x);if (p == nullptr) { cout << "出队失败" << endl; return false; }rear->next = p;rear = p;cout << "元素" << x << "入队成功" << endl; return true;
}
bool LinkQueue::DeQueue(int& x) {if (IsEmpty() == true) { cout << "入队失败" << endl; return false; }LinkNode* p = front->next;x = p->data;front->next = p->next;delete p;cout << "元素" << x << "出队成功" << endl; return true;
}int main()
{LinkQueue q;int x;q.EnQueue(1); // 队q:1q.EnQueue(2); // 队q:1 2q.EnQueue(3); // 队q:1 2 3q.DeQueue(x); // 队q:2 3q.EnQueue(4); // 队q:2 3 4q.EnQueue(5); // 队q:2 3 4 5q.EnQueue(6); // 队q:2 3 4 5 6q.DeQueue(x); // 队q:3 4 5 6q.EnQueue(7); // 队q:3 4 5 6 7q.EnQueue(8); // 队q:3 4 5 6 7 8q.DeQueue(x); // 队q:4 5 6 7 8q.DeQueue(x); // 队q:5 6 7 8q.DeQueue(x); // 队q:6 7 8q.DeQueue(x); // 队q:7 8q.DeQueue(x); // 队q:8q.DeQueue(x); // 队q: 空q.DeQueue(x); // 队列为空, 出队失败return 0;
}

⌨️算法代码(循环单链表版本)

#include <iostream>
using namespace std;typedef struct LinkNode {int data;LinkNode* next;LinkNode() : data(0), next(nullptr) {}LinkNode(int x) : data(x), next(nullptr) {}
}LinkNode;class LinkQueue {
private:LinkNode* head;LinkNode* front;LinkNode* rear;
public:LinkQueue();~LinkQueue();bool IsEmpty();bool EnQueue(int x);bool DeQueue(int& x);
};LinkQueue::LinkQueue() {head = new LinkNode;front = rear = head;
}
LinkQueue::~LinkQueue() {delete head;
}
bool LinkQueue::IsEmpty() {if (head->next == head) { cout << "队列为空 "; return true; }else { cout << "队列不空 "; return false; }
}
bool LinkQueue::EnQueue(int x) {LinkNode* p = new LinkNode(x);if (p == nullptr) { cout << "入队失败" << endl; return false; } // 分配结点失败(内存已满rear->next = p;rear = p;rear->next = front;cout << "元素" << x << "入队成功" << endl; return true;
}
bool LinkQueue::DeQueue(int& x) {if (IsEmpty() == true) { cout << "出队失败" << endl; return false; }LinkNode* p = front->next;x = p->data;front->next = p->next;delete p;cout << "元素" << x << "出队成功" << endl; return true;
}int main()
{LinkQueue q;int x;q.EnQueue(1); // 队q:1q.EnQueue(2); // 队q:1 2q.EnQueue(3); // 队q:1 2 3q.DeQueue(x); // 队q:2 3q.EnQueue(4); // 队q:2 3 4q.EnQueue(5); // 队q:2 3 4 5q.EnQueue(6); // 队q:2 3 4 5 6q.DeQueue(x); // 队q:3 4 5 6q.EnQueue(7); // 队q:3 4 5 6 7q.EnQueue(8); // 队q:3 4 5 6 7 8q.DeQueue(x); // 队q:4 5 6 7 8q.DeQueue(x); // 队q:5 6 7 8q.DeQueue(x); // 队q:6 7 8q.DeQueue(x); // 队q:7 8q.DeQueue(x); // 队q:8q.DeQueue(x); // 队q: 空q.DeQueue(x); // 队列为空, 出队失败return 0;
}


🔚结语

博文到此结束,写得模糊或者有误之处,欢迎小伙伴留言讨论与批评,督促博主优化内容{例如有错误、难理解、不简洁、缺功能}等,博主会顶锅前来修改~😶‍🌫️

我是梅头脑,本片博文若有帮助,欢迎小伙伴动动可爱的小手默默给个赞支持一下,收到点赞的话,博主肝文的动力++~🌟🌟

同系列的博文:🌸数据结构_梅头脑_的博客-CSDN博客

同博主的博文:🌸随笔03 笔记整理-CSDN博客

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

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

相关文章

实战-后台管理系统SQL注入漏洞

对于edu来说&#xff0c;是新人挖洞较好的平台&#xff0c;本次记录一次走运的捡漏0x01 前景 在进行fofa盲打站点的时候&#xff0c;来到了一个后台管理处看到集市二字&#xff0c;应该是edu站点 确认目标身份&#xff08;使用的quake进行然后去ipc备案查询&#xff09; 网…

Qt实现Kermit协议(一)

1 概述 Kermit文件运输协议提供了一条从大型计算机下载文件到微机的途径。它已被用于进行公用数据传输。 其特性如下: Kermit文件运输协议是一个半双工的通信协议。它支持7位ASCII字符。数据以可多达96字节长度的可变长度的分组形式传输。对每个被传送分组需要一个确认。Kerm…

关于视场角,你需要知道这些!

视场角在光学工程中又称视场&#xff0c;视场角的大小决定了光学仪器的视野范围。视场角又可用FOV&#xff08;Field of view&#xff09;表示&#xff0c;其与焦距的关系如下&#xff1a;像高 EFL*tan (半FOV)&#xff1b;EFL为焦距&#xff1b;FOV为视场角。即以入瞳位置为顶…

一个包一条命令,我实现了对整个前端项目代码的校验

在现代前端开发中&#xff0c;代码校验与风格统一不仅是良好编程习惯的体现&#xff0c;更是提升项目质量、保障代码可维护性与减少潜在bug的关键环节。然而&#xff0c;面对诸如ESLint、Commitlint、Stylelint等多样化的校验工具&#xff0c;以及针对React、Vue等不同前端框架…

笔记本电脑上部署LLaMA-2中文模型

尝试在macbook上部署LLaMA-2的中文模型的详细过程。 &#xff08;1&#xff09;环境准备 MacBook Pro(M2 Max/32G); VMware Fusion Player 版本 13.5.1 (23298085); Ubuntu 22.04.2 LTS; 给linux虚拟机分配8*core CPU 16G RAM。 我这里用的是16bit的量化模型&#xff0c;…

java线程(一)--进程,多线程,synchronized和lock锁,JUC,JUnit

Java线程入门 单核CPU和多核CPU的理解 单核CPU&#xff0c;其实是一种假的多线程&#xff0c;因为在一个时间单元内&#xff0c;也只能执行一个线程的任务。例如&#xff1a;虽然有多车道&#xff0c;但是收费站只有一个工作人员在收费&#xff0c;只有收了费才能通过&#xf…

LeetCode226:反转二叉树

题目描述 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 解题思想 使用前序遍历和后序遍历比较方便 代码 class Solution { public:TreeNode* invertTree(TreeNode* root) {if (root nullptr) return root;swap(root->left, root…

什么是ISP住宅IP?相比于普通IP它的优势是什么?

什么是ISP住宅IP&#xff1f; ISP住宅IP是指由互联网服务提供商&#xff08;ISP&#xff09;分配给住宅用户的IP地址。它是用户在家庭网络环境中连接互联网的标识符&#xff0c;通常用于上网浏览、数据传输等活动。ISP住宅IP可以是动态分配的&#xff0c;即每次连接时都可能会…

BOM系统:贯穿制造全程的管理利器

在制造行业中&#xff0c;BOM系统的应用已经成为提高生产效率、降低成本和确保产品质量的关键因素。BOM系统作为产品结构和物料清单的管理工具&#xff0c;为制造企业提供了全面的控制和协同能力。 1.产品设计与开发&#xff1a;在产品设计阶段&#xff0c;BOM系统为工程师提供…

基于自动编码器的预训练模型方法模型预训练方法RetroMAE和RetroMAE-2

文章目录 RetroMAERetroMAE详情编码解码增强解码 RetroMAE-2RetroMAE-2详情编码[CLS]解码OT解码和训练目标向量表征 总结参考资料 RetroMAE RetroMAE 出自论文《RetroMAE: Pre-Training Retrieval-oriented Language Models Via Masked Auto-Encoder》&#xff0c;是一种针对于…

ES-7.12-官方文档阅读-ILM-Automate rollover

教程&#xff1a;使用ILM自动化滚动创建index 当你持续将带有时间戳的文档index到Elasticsearch当中时&#xff0c;通常会使用数据流&#xff08;data streams&#xff09;以便可以定义滚到到新索引。这是你能够实施一个hot-warm-cold架构来满足你的性能要强&#xff0c;控制随…

OpenHarmony实战:RK3568 开发板镜像烧录指南

前言 烧录开发板是每个开发者的必修课&#xff0c;每次对系统的修改务必进行烧录测试&#xff0c;确保修改正确和不会引入新问题。 本文基于 Windows10&#xff0c;以 RK3568 开发板为例&#xff0c;指导如何烧录 OpenHarmony 镜像&#xff0c;镜像也叫固件。Hihoop&#xff…

Oracle利用BBED恢复崩溃实例(ORA-01092,ORA-00704,ORA-01578)

BBED修复数据损坏引起的数据库崩溃&#xff08;ORA-01092,ORA-00704,ORA-01578&#xff09;(2021年某苏州国企的案例&#xff09; 1.Symptom 用户一个边缘系统出现数据文件损坏&#xff0c;且没有备份&#xff0c;数据库无法启动 报错如下&#xff0c;发现是oracle bootstra…

【Vue3进阶】- 第2学堂小商城实战课程前言

该教程为进阶教程&#xff0c;如果你还不了解Vue3的基础知识&#xff0c;可以先前往Vue3基础教程&#xff0c;从入门到实战。 学习时遇到的任何疑问都欢迎在相应课文页面下方的问答区进行提问哦 我能学到什么&#xff1f; 编程写法千千万&#xff0c;实现需求是第一。 教程中…

Docker容器、Serverless与微服务:腾讯云云原生架构技术实践案例集解析

前言 随着云原生技术的飞速发展&#xff0c;容器化和函数计算正成为企业和开发者关注的焦点。在这一潮流中&#xff0c;腾讯云凭借其卓越的技术实力和深厚的行业积累&#xff0c;发布了《2023腾讯云容器和函数计算技术实践精选集》&#xff0c;为我们提供了一份深入探索云原生…

CAS(Compare And Swap)

目录 CAS概念 乐观锁与悲观锁 ABA问题 Unsafe类 ​编辑 原子类 基本类型原子类 原子引用类 原子数组 原子更新器类 原子累加器 CAS概念 CAS是Compare And Swap的缩写&#xff0c;中文翻译成&#xff1a;比较并交换&#xff0c;实现无锁并发时常用到的一种技术。它一…

3.Labview字符串与路径精讲(下) — 字符串及路径的用法汇总

本章讲解labview中的字符串和路径具体实践用例&#xff0c;从前面板字符串属性到后面板字符串函数应用做出详细概述&#xff0c;通过本文的学习希望大家了解到字符串及路径在labview编程中的重要地位。 本系列文章为labview 从基础到强化到精通的学习文章&#xff0c;大家可以随…

奥比中光深度相机(二):PyQt5实现打开深度摄像头功能

文章目录 奥比中光深度相机&#xff08;二&#xff09;&#xff1a;PyQt5实现打开深度摄像头功能官方给出的调用深度相机源码环境精炼 UI界面设计逻辑代码构建槽函数连接提取视频流在界面中显示深度视频流注意关闭相机 总体代码效果演示运行main.py代码选择相机打开摄像头关闭摄…

HarmonyOS实战开发-如何实现一个简单的健康生活应用(上)

介绍 本篇Codelab介绍了如何实现一个简单的健康生活应用&#xff0c;主要功能包括&#xff1a; 用户可以创建最多6个健康生活任务&#xff08;早起&#xff0c;喝水&#xff0c;吃苹果&#xff0c;每日微笑&#xff0c;刷牙&#xff0c;早睡&#xff09;&#xff0c;并设置任…

BabySQL【2019极客大挑战】

知识点&#xff1a; 功能分析 登录界面一般是 where username and password 可以从username出手&#xff0c;注释掉and语句单引号闭合绕过 通过测试和报错信息发现是一个单引号读取输入可以单引号闭合绕过关键字过滤 or and 过滤 || &&替换双写绕过select from wher…