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

news2024/11/25 14:54:32

  

考研笔记整理~🥝🥝

之前的博文链接在此:数据结构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中的元素全部入栈s
	while (!q.empty()) {
		s.push(q.front());
		q.pop();
	}
 
	// 栈s中的元素全部入队列q
	while (!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 2
	q.Enqueue(4); // 栈S1:4,栈S2:3 2
	q.Enqueue(5); // 栈S1:4 5,栈S2:3 2
	q.Enqueue(6); // 栈S1:4 5 6,栈S2:3 2
	q.Dequeue(x); // 栈S1:4 5 6,栈S2:3 
	q.Enqueue(7); // 栈S1:4 5 6 7,栈S2:3
	q.Enqueue(8); // 队列已满, 入队失败
	q.Dequeue(x); // 栈S1:4 5 6 7,栈S2:空
	q.Dequeue(x); // 栈S1:空,栈S2:7 6 5 4
	q.Dequeue(x); // 栈S1:空,栈S2:7 6 5
	q.Dequeue(x); // 栈S1:空,栈S2:7 6
	q.Dequeue(x); // 栈S1:空,栈S2:7
	q.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:1
	q.EnQueue(2); // 队q:1 2
	q.EnQueue(3); // 队q:1 2 3
	q.DeQueue(x); // 队q:2 3
	q.EnQueue(4); // 队q:2 3 4
	q.EnQueue(5); // 队q:2 3 4 5
	q.EnQueue(6); // 队q:2 3 4 5 6
	q.DeQueue(x); // 队q:3 4 5 6
	q.EnQueue(7); // 队q:3 4 5 6 7
	q.EnQueue(8); // 队q:3 4 5 6 7 8
	q.DeQueue(x); // 队q:4 5 6 7 8
	q.DeQueue(x); // 队q:5 6 7 8
	q.DeQueue(x); // 队q:6 7 8
	q.DeQueue(x); // 队q:7 8
	q.DeQueue(x); // 队q:8
	q.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:1
	q.EnQueue(2); // 队q:1 2
	q.EnQueue(3); // 队q:1 2 3
	q.DeQueue(x); // 队q:2 3
	q.EnQueue(4); // 队q:2 3 4
	q.EnQueue(5); // 队q:2 3 4 5
	q.EnQueue(6); // 队q:2 3 4 5 6
	q.DeQueue(x); // 队q:3 4 5 6
	q.EnQueue(7); // 队q:3 4 5 6 7
	q.EnQueue(8); // 队q:3 4 5 6 7 8
	q.DeQueue(x); // 队q:4 5 6 7 8
	q.DeQueue(x); // 队q:5 6 7 8
	q.DeQueue(x); // 队q:6 7 8
	q.DeQueue(x); // 队q:7 8
	q.DeQueue(x); // 队q:8
	q.DeQueue(x); // 队q: 空
	q.DeQueue(x); // 队列为空, 出队失败

	return 0;
}


🔚结语

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

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

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

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

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

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

相关文章

Mamba和状态空间模型(SSM)的视觉指南:替代 Transformers 的语言建模方法

原文地址&#xff1a; A Visual Guide to Mamba and State Space Models 2024 年 2 月 19 日 论文地址&#xff1a;https://arxiv.org/pdf/2312.00752.pdf 这篇论文介绍了一种新型的线性时间序列模型Mamba&#xff0c;它通过选择性状态空间&#xff08;Selective State Space…

【Redis持久化】RDB、ROB介绍和使用

RDB、ROB介绍和使用 引言ROB介绍配置指令介绍使用指令&#xff1a;dump文件修复指令快照禁用 AOF工作流程&#xff1a;文件重写&#xff1a;三种写回策略&#xff1a; 混合使用 引言 持久化的目的&#xff0c;其实就是在Redis重启或者中途崩溃的时候能够依靠自身恢复数据&…

953: 单链表的删除操作的实现

学习版 【C语言】 【C】 #include <iostream>class MyLinkedList{public:struct LinkedNode{int val;LinkedNode* next;LinkedNode(int x):val(x),next(NULL){};}; MyLinkedList(){dummyHeadnew LinkedNode(0);length0;}~MyLinkedList(){while (dummyHead){LinkedNode…

vulhub打靶记录——driftingbox

文章目录 主机发现端口扫描目录扫描爆破子域名提权总结 主机发现 使用nmap扫描局域网内存活的主机&#xff0c;命令如下&#xff1a; nmap -sP 192.168.56.0/24192.168.56.1&#xff1a;主机IP&#xff1b;192.168.56.100&#xff1a;DHCP服务器IP&#xff1b;192.168.56.101…

代码随想录第二十六天 | 回溯算法P3 |● 39. ● 40.● 131.

39. 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重…

windows下部署llama.cpp

下载cmake 下载地址 解压&#xff0c;设置Path环境变量D:\CMake\bin 打开cmd输入cmake -version 安装mingw powershell下执行 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser iex "& {$(irm get.scoop.sh)} -RunAsAdmin" scoop bucket add extras s…

蓝桥杯算法题——暴力枚举法

先估算这个数小于3的50次方 cnt0 for i in range(50):for j in range(50):for k in range(50):a3**ib5**jc7**kif a*b*c<59084709587505:cnt1 print(cnt-1)#当ijk都为0时&#xff0c;a*b*c1不是幸运数字所以要减去

C++笔记:命名空间

引入&#xff1a; 平常&#xff0c;我们在进行C编写时&#xff0c;一般我们都会默认在开始去写这样的代码&#xff1a; #include<iostream>//包含头文件using namespace std;//展开命名空间 这里就出现了与C语言不同的地方&#xff1a;这里的命名空间就是C对于C语言进…

深度学习| DiceLoss解决图像数据不平衡问题

图像数据不平衡问题 图像数据不平衡&#xff1a;在进行图像分割时&#xff0c;二分类问题中&#xff0c;背景过大&#xff0c;前景过小&#xff1b;多分类问题中&#xff0c;某一类别的物体体积过小。在很多图像数据的时候都会遇到这个情况&#xff0c;尤其是在医学图像处理的…

如何快速掌握数字化运维方法,构建数字化运维体系?

⛳️ 写在前面参与规则&#xff01;&#xff01;&#xff01; ✅参与方式&#xff1a;关注博主、点赞、收藏、评论&#xff0c;任意评论&#xff08;每人最多评论三次&#xff09; ⛳️本次送书1~4本【取决于阅读量&#xff0c;阅读量越多&#xff0c;送的越多】 主要内容读者…

操作符:左移(<<)右移(>>)

在介绍移位操作符前&#xff0c;我们先介绍一下原码反码和补码 这里要讲的左移和右移牵扯到原码补码和反码&#xff0c; 原码即这个整数转化为2进制时的一串&#xff0c; 正整数的原码、反码、补码相同&#xff0c; 10&#xff08;int类型&#xff09;的原码&#xff1a;00…

day4 linux上部署第一个nest项目(java转ts全栈/3R教室)

背景&#xff1a;上一篇吧nest-vben-admin项目&#xff0c;再开发环境上跑通了&#xff0c;并且build出来了dist文件&#xff0c;接下来再部署到linux试试吧 dist文件夹是干嘛的&#xff1f; 一个pnpn install 直接生成了两个dist文件夹&#xff0c;前端admin项目一个&#xf…

黑马鸿蒙笔记 3

目录 11.ArkUI组件-Column和Row 12.ArkUI组件-循环控制 13.ArkUI组件-List 14.ArkUI组件-自定义组件 15.ArkUI组件-状态管理State装饰器 16.ArkUI组件-状态管理-任务统计案例 17.ArkUI组件-状态管理-PropLinkProvideConsume 11.ArkUI组件-Column和Row Colum和Row的交叉…

力扣-python-故障键盘

题解&#xff1a; from collections import dequeclass Solution:def finalString(self, s: str) -> str:# 创建一个双端队列用于存储字符q deque()# 定义一个标志位&#xff0c;用于标记当前字符应该添加到队列的哪一端head False# 遍历输入的字符串s的每一个字符for ch…

k8s安装traefik作为ingress

一、先来介绍下Ingress Ingress 这个东西是 1.2 后才出现的&#xff0c;通过 Ingress 用户可以实现使用 nginx 等开源的反向代理负载均衡器实现对外暴露服务&#xff0c;以下详细说一下 Ingress&#xff0c;毕竟 traefik 用的就是 Ingress 使用 Ingress 时一般会有三个组件: …

从0到1利用express搭建后端服务

目录 1 架构的选择2 环境搭建3 安装express4 创建启动文件5 express的核心功能6 加入日志记录功能7 日志记录的好处本节代码总结 不知不觉学习低代码已经进入第四个年头了&#xff0c;既然低代码很好&#xff0c;为什么突然又自己架构起后端了呢&#xff1f;我有一句话叫低代码…

大模型 web ui 界面 text-generation-webui

目录 前言 web ui ValueError: When localhost is not accessible 前言 使用 text-generation-webui 生成大模型界面&#xff0c;这个是专门用于文本对话生成的 web ui 界面 GitHub - oobabooga/text-generation-webui: A Gradio web UI for Large Language Models. Suppo…

【语言信号增强算法研究-1】维纳滤波(Wiener Filter)

1 语音增强方法分类 2 维纳滤波的局限性 对于非线性和非高斯噪声的处理效果不佳&#xff1b; 对于信号和噪声的统计特性要求比较高&#xff0c;需要准确地了解信号和噪声的分布规律&#xff08;说明自适应很差&#xff09;&#xff1b; 在处理复杂信号时&#xff0c;需要进行多…

【Functional Affordances】如何确认可抓取的区域?(前传)

文章目录 1. 【Meta AI】Emerging Properties in Self-Supervised Vision Transformers2. 【Meta AI】DINOv2: Learning Robust Visual Features without Supervision3. 【NeurIPS 2023】Diffusion Hyperfeatures: Searching Through Time and Space for Semantic Corresponden…

ElasticSearch理论指导

引子 本文致力于ElasticSearch理论体系构建&#xff0c;从基本概念和术语讲起&#xff0c;具体阐述了倒排索引和TransLog&#xff0c;接着讲了ElasticSearch的增删改查的流程和原理&#xff0c;最后讲了讲集群的选举和脑裂问题。 前言 大碗宽面-Kafka一本道万事通&#xff0…