栈和队列--数据结构初阶(2)(C/C++)
文章目录
- 前言
- 理论部分
- 栈的模拟实现
- STL中的栈容器
- 队列的模拟实现
- STL中的队列容器
- 作业部分
前言
这期的话会给大家讲解栈和队列的模拟实现和在STL中栈和队列怎么用的一些知识和习题部分(这部分侧重于理论知识,习题倒还是不难)
理论部分
栈的模拟实现
typedef int STDataType;typedef struct Stack
{STDataType* a;//这里的a想表示的是数组int top;//表示数组a当前的容量int capacity;
}ST;void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);if (ps->a == NULL){perror("malloc fail");return;}ps->capacity = 4;ps->top = 0;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * ps->capacity*2);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity *= 2;}ps->a[ps->top] = x;ps->top++;
}void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;
}int STSize(ST* ps)
{assert(ps);return ps->top;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}//拓展:bool里面如果return的是数字的话,会隐式转换STDataType STTop(ST* ps)
{assert(ps);assert(!STEmpty(ps));return ps->a[ps->top - 1];
}
注意:这样写的话,此时的栈顶的下标是top-1
stPush那里一般用ps->top == ps->capacity
top那里是还没存元素的
开空间完记得检查是否开辟成功
尽量不要用while(st.top!=0去代替while(!STEmpty(&st))),数据结构最好封装起来
注意STTop最后那里是ps->a[ps->top-1]
这个代码有个问题:封装时一般要typedef类型,这里搞了但是没去用(让以后要改类型时只用改一次)
STL中的栈容器
stack容器(栈)
头文件:#include<stack>
创建:stack<T>st;//st是变量名,可以改;T是任意类型的数据
size empty
push:进栈
pop:出栈
top:返回栈顶元素,但是不会删除栈顶元素(先进后出)
队列的模拟实现
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef char QDatatype;typedef struct QueueNode
{struct QueueNode* next;QDatatype data;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDatatype x);
void QueuePop(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
QDatatype QueueFront(Queue* pq);
QDatatype QueueBack(Queue* pq);void QueueInit(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}void QueuePush(Queue* pq, QDatatype x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->data = x;newnode->next = NULL;if (pq->head == NULL){assert(pq->tail == NULL);pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);assert(pq->head != NULL);if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}QDatatype QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}QDatatype QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}
结构体定义那里可以像这样在结构体里面用自己的指针
结构体1里面套结构体2的话,定义结构体1后不用单独手动再为结构体1中的结构体2开辟
跟定义int指针,想变成数组需要malloc区分
注意:assert检查的是结果为0,就会报错
STL中的队列容器
queue(队列):
头文件:#include<queue>
创建:queue<T>q;//q是变量名,T是任意类型的数据
size empty push pop
front:返回队头元素,但不会删除
back:返回队尾元素,但不会删除
不可以用clear来直接清除队列pop删除的是队头
作业部分
力扣 有效的括号
力扣 有效的括号
注意点:右括号数量不等于左括号这个特殊情况不要忘了
感悟:像这种如果匹配的话要继续走,不匹配的话要干啥的if里面写不匹配的条件会好些代码实现:
typedef struct Stack
{char*a;int top;int capacity;}void STInit(){a = (char*)malloc(sizeof(char)*4);capacity = 4;top = 0;}void STPush(char*ps,char x){assert(ps);if(ps->top == ps->capacity){a = (char*)malloc(sizeof(char)*ps->capacity*2);capacity*=2;}ps->a[ps->top] = x;ps->top++;}void STPop(char*ps,char x){assert(ps);ps->top--;}bool isValid(char* s) {struct Stack;&a = &s;}
if如果判断条件多的话可以像下面这样写,这样写不用续行符
而且if后面只跟一个语句的话,一般跟if写同一行上

企业中的话,能初始化的尽量还是要初始化一下,竞赛一般不用
力扣 用栈实现队列
题目: 力扣 用栈实现队列
相比用队列实现栈可以优化的地方是:可以有个栈专门入栈,一个栈专门出栈,出栈的空了再把另一个栈倒过来代码实现:
class MyQueue {
public:stack<int>q1;stack<int>q2;int count1 = 0;//用q1来存入栈,q2来搞出栈void push(int x) {q1.push(x);}int pop() {if(!q2.empty()){int m = q2.top();q2.pop();return m;}else{while(q1.size()){int k = q1.top();q2.push(k); q1.pop();}int n = q2.top();q2.pop();return n;}}int peek() {if(!q2.empty()){return q2.top();}else {while(q1.size()){q2.push(q1.top()); q1.pop();}return q2.top();}}bool empty() {if(q1.empty()&&q2.empty())return true;else{return false;}}
};
力扣 设计循环队列
题目:力扣 设计循环队列
这里用链表模拟队列不好(因为要找尾)所以用数组来模拟
想让数组也能循环的话,就要时不时让他对k取模(插入,删除过程中也要)
由这个题引申出来的知识有:
1.malloc了几次,后续也要free几次,虽然说不free也可以通过,但是要是在面试中就是减分项,比如下面这种malloc的方式


代码实现:typedef struct {int*a;int front;int rear;int k;} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue*obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->front = obj->rear = 0;obj->k = k;obj->a = (int*)malloc(sizeof(int)*(k+1));return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->front == obj->rear;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->rear+1)%(obj->k+1) == obj->front;//这里的作用是让rear在数组末时可以返回到0那去以及防止是空
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj)) return false;obj->a[obj->rear] = value;obj->rear = ((++obj->rear))%(obj->k+1);return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)) return false;obj->front = (++obj->front)%(obj->k+1);return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[(obj->rear-1+obj->k+1)%(obj->k+1)];
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}
队列和栈都属于线性数据结构 循环队列也是线性数据结构
相关文章:
栈和队列--数据结构初阶(2)(C/C++)
文章目录 前言理论部分栈的模拟实现STL中的栈容器队列的模拟实现STL中的队列容器 作业部分 前言 这期的话会给大家讲解栈和队列的模拟实现和在STL中栈和队列怎么用的一些知识和习题部分(这部分侧重于理论知识,习题倒还是不难) 理论部分 栈的模拟实现 typedef int…...
C++常用函数合集
万能头文件:#include<bits/stdc.h> 1. 输入输出流(I/O)函数 1.1cin 用于从标准输入流读取数据。 1.2cout 用于向标准输出流写入数据。 // 输入输出流(I/O)函数 #include <iostream> using namespace…...
OpenGL shader开发实战学习笔记:第十二章 深入光照
1. 深入光照 1.1. 平行光 我们在前面的章节中,已经介绍了平行光的基本原理和实现步骤 平行光的基本原理是,所有的光都从同一个方向照射到物体上,这个方向就是平行光的方向。 1.2. 点光源 点光源的基本原理是,所有的光都从一个…...
CentOS7系统安装Docker教程
一、安装前准备 1、检查系统环境:Docker 要求系统为 64 位,且内核版本 3.10 以上。通过uname -r命令查看当前系统内核版本 。比如执行uname -r后,显示3.10.0-1160.el7.x86_64 ,说明满足内核版本要求。 2、卸载旧版本(…...
获取电脑信息(登录电脑的进程、C盘文件信息、浏览器信息、IP)
电脑的进程信息 // 获取登录电脑的进程信息String os System.getProperty("os.name").toLowerCase();String command;if (os.contains("win")) {command "tasklist";} else {command "ps -ef";}try {Process process new ProcessB…...
PCB 射频天线设计和版图创建技巧
本文要点 射频天线有多种形式,从整合在芯片中的扁平天线,到直接印制在PCB上的铜质天线。 创建带有一个或多个天线的版图时,需要确保在PCB不同电路模块之间彼此隔离。 在设计一个射频天线时,应该使用CAD工具,此类…...
uniapp-商城-29-vuex 关于系统状态的管理
按照我们前面讲的,vuex,的使用方式: 步骤如下: 1 先创建store 文件夹 2 在 store 中 创建一个 index.js 3、 在 store 中,创建一个modules文件夹 4、在store中,创建一个getters.js 5、在modules文件…...
小迪安全-112-yii反序列化链,某达oa,某商场,影响分析
yii是和tp一样的框架 入口文件 web目录下 相对tp比较简单一些,对比tp找一下他的url结构 对应的位置结构 这个contorllers文件的actionindex就是触发的方法 控制器,指向的index文件,就可以去视图模块看index文件 这就是前端展示的文件 自…...
区间选点详解
步骤 operator< 的作用在 C 中, operator< 是一个运算符重载函数,它定义了如何比较两个对象的大小。在 std::sort 函数中,它会用到这个比较函数来决定排序的顺序。 在 sort 中,默认会使用 < 运算符来比较两个对象…...
如何在白平衡标定种构建不同类型的白平衡色温坐标系
目录 一、预备知识: 二、常见的白平衡色温坐标系 三、白平衡色温坐标系的理解 1)横纵坐标轴分别代表什么含义? 2)色温坐标系中原点表示什么含义? 3)某M/某H的色温坐标为什么是长成这样呢?…...
Oracle RMAN同步数据库Active database duplicate
Active database duplicate,不需要先把目标数据库进行rman备份,只要目标数据库处于归档模式下即可直接通过网络对数据库进行copy,且copy完成后自动open数据库。这对于大数据特别是T级别的数据库来说优点非常明显,复制前不需要进行…...
Spring MVC 一个简单的多文件上传
原始代码逐行解释 PostMapping("/uploads") // ① 声明处理POST请求,路径为"/uploads" ResponseBody // ② 直接返回数据到响应体,不进行视图解析 public String uploads(MultipartFile[] files, // …...
基于DeepSeek/AI的资产测绘与威胁图谱构建
引言: 在网络安全攻防实践中,资产测绘是红队作战与蓝队安全运营的第一步,其本质都是通过系统性信息采集实现攻击面管理。 当前普遍存在的痛点在于,当企业级资产规模呈指数级增长时,传统基于规则引擎的低效批量处理方式…...
构建自动翻译工作流:技术与实践
一、引言 制药行业客户迫切需要一种翻译解决方案,以解决公司内部多样化的翻译难题。他们需要的不仅是提升翻译效率和准确性的工具,更希望能够保持文档的原始格式。我们观察到客户的需求广泛,包括多语言办公文件、研究文档和药品报批文件等&a…...
【Linux】中的网络管理
目录 1.ipv4原理,网关与DNS定义 2ip图形化配置--nm 2.1图形化平台配置 2.2无图形化平台配置 3.常用的网络命令--ping,wget,curl ping wget curl 4.ip命令临时配置---ifconfig,ip a ifconfig ip address 5.ip命令永久配…...
前端面试每日三题 - Day 10
这是我为准备前端/全栈开发工程师面试整理的第十天每日三题练习,涵盖: JavaScript 中 this 的指向详解与常见陷阱Vue 生命周期钩子的执行顺序与场景实践(Vue2 vs Vue3)系统设计实战:内容推荐系统的核心架构设计 ✅ 题…...
《深度学习》课程之卷积神经网络原理与实践教学设计方案
《深度学习》课程之卷积神经网络原理与实践教学设计方案 一、教学目标设计 (一)知识目标 学生能够准确描述卷积神经网络(CNN)的基本定义,包括其核心组成部分(如卷积层、池化层、全连接层等)及…...
elasticsearch中文分词器插件下载教程
一、下载原因: 我们的业务中通常使⽤的是中⽂分词,es的中⽂分词默认会将中⽂词每个字看成⼀个词⽐如:“我想吃⾁夹馍”会被分为”我”,”想”,”吃”,”⾁” ,”夹”,”馍” 这显然是…...
门面模式与适配器模式
一、门面模式 门面模式:提供统一接口访问子系统接口 1、包含角色 外观系统对外的统一接口子系统类的集合;并不知道外观角色的存在,需要为了配合外观角色而做特殊处理或修改 2、举例 原本开关灯要分别操作各个房间的灯,现在设置总…...
QSS【QT】
文章目录 QSSid选择器 & 类型选择器伪类选择器盒子模型 QSS 设置样式的时候,是可以指定某个控件来设置的。 指定控件之后,此时的样式就会针对这个指定的控件,也会针对子控件生效 ui->pushButton_2->setStyleSheet("QPushButt…...
第十六节:高频开放题-React与Vue设计哲学差异
响应式原理(Proxy vs 虚拟DOM) 组合式API vs Hooks React 与 Vue 设计哲学差异深度解析 一、响应式原理的底层实现差异 1. Vue 的响应式模型(Proxy/数据劫持) Vue 的响应式系统通过 数据劫持 实现自动依赖追踪: • …...
css 中float属性及clear的释疑
float属性可以让元素脱离文档流,父元素中的子元素设置为float,则会导致父元素的高度塌陷。 <style type"text/css"> .father{ /*没有给父元素定义高度*/background:#ccc; border:1px dashed #999; } .box01,.box02,.box0…...
缓存 --- 内存缓存 or 分布式缓存
缓存 --- 内存缓存 or 分布式缓存 内存缓存(In-Memory Cache)分布式缓存(Distributed Cache)内存缓存 vs 分布式缓存 内存缓存和分布式缓存是两种常见的缓存策略,它们在存储位置、访问速度和适用场景上有所不同。下面分…...
2025.4.17总结
工作:今天对需求的测试设计进行了完善,然后,对测试设计进行了评审,最后提了个问题单。 反思这个过程,要说不足的地方,就是评审的时候总觉得自己吐字不清晰,表达能力早就想提升了,但…...
BH1750光照传感器---附代码
目录 BH1750简介BH1750指令集BH1750工作流程 BH1750简介 VCC-->电源正; ADDR-->地址端口; GND-->电源负; PA5-->SDA-->I2C数据线; PA3-->SCL-->I2C时钟线; DVI-->I2C端口参考电压;…...
机器学习在催化剂设计中的应用理论加实操
背景介绍 数据智能驱动,催化理性设计新纪元 催化材料设计是能源转化、化工合成及环境治理等领域的核心挑战。传统催化研究主要依赖密度泛函理论(DFT)计算与实验试错法,通过量子力学模拟揭示活性位点电子结构,结合高通量实验筛选候选…...
蔡浩宇的AIGC游戏革命:从《原神》到《Whispers》的技术跨越
目录 引言:游戏行业的AI革命前夜 一、《Whispers》的技术突破与市场挑战 1.1 多模态AI技术的集成应用 1.2 与传统游戏的差异化体验 1.3 面临的商业化难题 二、从《原神》到《Whispers》的技术演进 2.1 《原神》成功的时代因素分析 2.2 蔡浩宇的技术路线转变 …...
Docker Compose 命令实现动态构建和部署
Docker Compose 命令实现动态构建和部署 一、编写支持动态版本号的 docker-compose.yml version: 3.8services:myapp:build: context: . # Dockerfile所在目录args:APP_VERSION: ${TAG:-latest} # 从环境变量获取版本号,默认latestimage: myapp:${TAG:-latest} …...
前端vue+typeScritp+elementPlus基础页面实现:
效果: 前端代码: index.vue: <template><el-container><el-main><el-card class"search-card" shadow"never"><transition :enter-active-class"proxy?.animate.searchAnimate.enter" :le…...
leetcode第20题(有效的括号)
思路解析(使用栈): 使用一个栈来保存左括号。 每当遇到一个右括号时,检查栈顶元素是否是匹配的左括号。 如果匹配,则弹出栈顶元素; 如果不匹配或者栈为空,则说明无效; 最后如果栈…...
