当前位置: 首页 > news >正文

栈和队列(数据结构刷题)[一]-python

文章目录

  • 前言
  • 一、原理介绍
  • 二、用栈实现队列
    • 1.操作
    • 2.思路
  • 三、关于面试考察
    • 栈里面的元素在内存中是连续分布的么?


前言

提到栈和队列,大家可能对它们的了解只停留在表面,再深入一点,好像知道又好像不知道的感觉。本文我将从底层实现和应用来介绍栈和队列。让大家更加通透的了解栈和队列。


一、原理介绍

栈和队列的原理是,队列是先进先出,栈是先进后出。示意图如下:
在这里插入图片描述

首先大家要了解栈和队列是C++ STL标准模版库里面的两个数据结构。栈stack是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能). STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)。栈提供push 和 pop 等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)。 不像是set 或者map 提供迭代器iterator来遍历所有元素。deque是一个双向队列,只要封住一段,只开通另一端就可以实现栈的逻辑了。
那么在STL中栈是用什么容器实现的呢?栈的底层实现可以是vector、deque、list都可以,主要是数组和链表的底层实现。
上面说的栈的特性,对应的队列情况是一样的。deque是一个双向队列,只要封住一段,只开通另一端就可以实现栈的逻辑了。队列中先进先出的数据结构,同样不允许有遍历行为,不提供迭代器, SGI STL中队列一样是以deque为缺省情况下的底部结构。
C++语言中,指定vector为栈的底层实现,初始化语句如下:

std::stack<int, std::vector<int> > third;  // 使用vector为底层容器的栈

也可以指定list为底层实现,初始化语句如下:

std::queue<int, std::list<int>> third; // 定义以list为底层容器的队列

所以STL 队列也不被归类为容器,而被归类为container adapter( 容器适配器)。
只有深挖栈和队列的内部原理,才能真的做到夯实基础。

二、用栈实现队列

1.操作

push(x) – 将一个元素放入队列的尾部
pop() – 从队列首部移除元素。
peek() – 返回队列首部的元素。
empty() – 返回队列是否为空。
举例:

MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek();  // 返回 1
queue.top();   // 返回 1
queue.empty(); // 返回 false

2.思路

leetcode 232. 用栈实现队列
这道题不涉及算法,是一道模拟题,考察对栈和队列的掌握程度。
使用栈来模拟队列的行为,需要两个栈,一个输入栈,一个输出栈,注意输入栈和输出栈的关系。
执行语句:
queue.push(1);
queue.push(2);
queue.pop(); 注意此时的输出栈的操作
queue.push(3);
queue.push(4);
queue.pop();
queue.pop();注意此时的输出栈的操作
queue.pop();
queue.empty();
C++代码

void push(int x){stackIn.push();
}
int pop(){if stackOut.empty()while(!stackIn.empty()){ //将入栈里的所有元素都加入到出栈里stackOut.push(stackIn.top());stackIn.pop();}result=stackOut.top();stackOut.pop();return result;
}
# peak和pop是类似的  
int peek(){//直接使用已有的pop函数result=this->pop()//极大的优化了代码的简洁性stackOut.push(result);// 因为pop函数弹出了元素res,所以再添加回去return result;

仔细体会上述过程,会发现简直太妙了!!!

在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。
最后如何判断队列为空呢?如果进栈和出栈都为空的话,说明模拟的队列为空了。
在代码实现的时候,会发现pop() 和 peek()两个函数功能类似,代码实现上也是类似的,可以思考一下如何把代码抽象一下。在工业级代码开发中,最要不得的就是实现一个类似的函数,直接吧代码粘过来改,这样的项目代码会越来越乱,一定要懂得复用,功能相近的函数要抽象出来,不要大量的复制粘贴,很容易出问题!!!
代码如下(示例):

class MyQueue:def __init__(self):"""in主要负责push,out主要负责pop"""self.stack_in = []self.stack_out = []def push(self, x: int) -> None:"""有新元素进来,就往in里面push"""self.stack_in.append(x)def pop(self) -> int:"""Removes the element from in front of queue and returns that element."""if self.empty():return Noneif self.stack_out:return self.stack_out.pop()else:for i in range(len(self.stack_in)):self.stack_out.append(self.stack_in.pop())return self.stack_out.pop()def peek(self) -> int:"""Get the front element."""ans = self.pop()self.stack_out.append(ans)return ansdef empty(self) -> bool:"""只要in或者out有元素,说明队列不为空"""return not (self.stack_in or self.stack_out)

上述代码中,peek()的实现,对pop()函数做了复用, 要不然,对stack_out( )判空的逻辑又要重写一遍。

leetcode. 225 用队列实现栈
操作如下:
push(x) – 元素x入栈
pop(x) – 删除栈顶元素
top(x) – 获取栈顶元素
empty() – 返回栈是否为空

void push(int x){que.push(x);
}
#关键在于如何弹出元素
#用一个队列实现栈的出元素
int pop(){size=que.size();#弹出size-1个数才能模拟栈弹出一个元素size--;while(size--){#吧size-1弹出的元素再重新加回队列里que.push(que.front());#取队列出口处的第一个元素但并没有弹出que.pop();#弹出刚取的第一个元素}	result=que.front();que.pop();return result	
}
#循环吧前size-1个元素再重次新添加进来 然后最后一个元素就是我么栈要出来的元素
#top函数就是我们 栈里面你想获取的第一个元素实际就是我队列里入口处第一个元素
int top(){return que.back()#队列入口处的第一个元素
}

总的来说,用一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。
Python完整代码:

from collections import deque
class MyStack:def __init__(self):self.que=deque()def push(self,x):self.que.append(x)def pop(self):if self.empty():return Nonefor i in range(len(self.que)-1):self.que.append(self.que.popleft())return self.que.popleft()def top(self):if self.empty():return Nonereturn self.que[-1]def empty(self):return not self.que()

三、关于面试考察

栈里面的元素在内存中是连续分布的么?

答:栈里面元素在内存中不是连续分布的。栈是容器适配器,底层容器使用不同的容器,导致栈内数据在内存中不是连续分布的。缺省情况下(构造函数缺省),默认底层容器是deque,deque在内存中的数据分布也是不连续分布。
(ps:近期都是关于数据结构基础知识分享,感兴趣的同学可以关注本人公众号:HEllO算法笔记)

相关文章:

栈和队列(数据结构刷题)[一]-python

文章目录 前言一、原理介绍二、用栈实现队列1.操作2.思路 三、关于面试考察栈里面的元素在内存中是连续分布的么&#xff1f; 前言 提到栈和队列&#xff0c;大家可能对它们的了解只停留在表面&#xff0c;再深入一点&#xff0c;好像知道又好像不知道的感觉。本文我将从底层实…...

【备战秋招】JAVA集合

集合 前言 一方面&#xff0c; 面向对象语言对事物的体现都是以对象的形式&#xff0c;为了方便对多个对象 的操作&#xff0c;就要 对对象进行存储。 另一方面&#xff0c;使用Array存储对象方面具有一些弊端&#xff0c;而Java 集合就像一种容器&#xff0c;可以动态地把多…...

setState详解

this. setState( [partialState], [callback]) 1.[partialState] :支持部分状态更改 this, setState({ x:100 //不论总共有多少状态&#xff0c;我们只修改了x&#xff0c;其余的状态不动 });callback :在状态更改/视图更新完毕后触发执行&#xff0c;也可以说只要执行了setS…...

Qt5.12.6配置Android Arm开发环境(windows)

1. 安装jdk1.8 2.安装Android Studio 并安装 SDK 与NDK SDK Tools 选择 26.0.3 SDK Platform 选择 Android SDK Platform 26 NDK选择19版本 安卓ARM环境配置成功如下: JDK1.8 , SDK 26 , NDK 19 在安装QT时要选择 ARMv7(32位CPU)与ARM64-v8a(64位CPU) 选择支持android平台…...

七、进程程序替换

文章目录 一、进程程序替换&#xff08;一&#xff09;概念&#xff08;二&#xff09;为什么程序替换&#xff08;三&#xff09;程序替换的原理&#xff08;四&#xff09;如何进行程序替换1. execl2. 引入进程创建——子进程执行程序替换&#xff0c;会不会影响父进程呢? &…...

C++核心编程——详解运算符重载

文章目录&#x1f4ac; 一.运算符重载基础知识①基本概念②运算符重载的规则③运算符重载形式④运算符重载建议 二.常用运算符重载①左移(<<)和右移(>>)运算符重载1️⃣重载后函数参数是什么&#xff1f;2️⃣重载的函数返回类型是什么&#xff1f;3️⃣重载为哪种…...

2023年前端面试汇总-CSS

1. CSS基础 1.1. CSS选择器及其优先级 对于选择器的优先级&#xff1a; 1. 标签选择器、伪元素选择器&#xff1a;1&#xff1b; 2. 类选择器、伪类选择器、属性选择器&#xff1a;10&#xff1b; 3. id 选择器&#xff1a;100&#xff1b; 4. 内联样式&#xff1a;1000&a…...

Java调用Pytorch实现以图搜图(附源码)

Java调用Pytorch实现以图搜图 设计技术栈&#xff1a; 1、ElasticSearch环境&#xff1b; 2、Python运行环境&#xff08;如果事先没有pytorch模型时&#xff0c;可以用python脚本创建模型&#xff09;&#xff1b; 1、运行效果 2、创建模型&#xff08;有则可以跳过&#xf…...

【EasyX】实时时钟

目录 实时时钟1. 绘制静态秒针2. 秒针的转动3. 根据实际时间转动4. 添加时针和分针5. 添加表盘刻度 实时时钟 本博客介绍利用EasyX实现一个实时钟表的小程序&#xff0c;同时学习时间函数的使用。 本文源码可从github获取 1. 绘制静态秒针 第一步定义钟表的中心坐标center&a…...

基于XC7Z100的PCIe采集卡(GMSL FMC采集卡)

GMSL 图像采集卡 特性 ● PCIe Gen2.0 X8 总线&#xff1b; ● 支持V4L2调用&#xff1b; ● 1路CAN接口&#xff1b; ● 6路/12路 GMSL1/2摄像头输入&#xff0c;最高可达8MP&#xff1b; ● 2路可定义相机同步触发输入/输出&#xff1b; 优势 ● 采用PCIe主卡与FMC子…...

Kibana:使用 Kibana 自带数据进行可视化(一)

在今天的练习中&#xff0c;我们将使用 Kibana 自带的数据来进行一些可视化的展示。希望对刚开始使用 Kibana 的用户有所帮助。 前提条件 如果你还没有安装好自己的 Elastic Stack&#xff0c;你可以参考如下的视频来开启 Elastic Stack 并进行下面的练习。你可以开通阿里云检…...

MySQL数据库基础 07

第七章 单行函数 1. 函数的理解1.1 什么是函数1.2 不同DBMS函数的差异1.3 MySQL的内置函数及分类 2. 数值函数2.1 基本函数2.2 角度与弧度互换函数2.3 三角函数2.4 指数与对数2.5 进制间的转换 3. 字符串函数4. 日期和时间函数4.1 获取日期、时间 4.2 日期与时间戳的转换 4.3 获…...

JVM | JVM垃圾回收

JVM | JVM垃圾回收 1、堆空间的基本结构2、内存分配和回收原则2.1、对象优先在 Eden 区分配2.2、大对象直接进入老年代2.3、长期存活的对象将进入老年代2.4、主要进行 gc 的区域2.5、空间分配担保3、死亡对象判断方法3.1、引用计数法3.2、可达性分析算法3.3、引用类型总结3.4、…...

avive零头撸矿

Avive 是一个透明的、自下而上替代自上而下的多元网络&#xff0c;旨在克服当前生态系统的局限性&#xff0c;实现去中心化社会。 aVive&#xff1a;一个基于 SBT 和市场的 deSoc&#xff0c;它使 dapps 能够与分散的位置 oracle 和 SBT 关系进行互操作。您的主权社交网络元宇宙…...

openGauss5.0之学习环境 Docker安装

文章目录 0.前言1. 准备软硬件安装环境1.1 软硬件环境要求1.2 修改操作系统配置1.2.1 关闭操作系统防火墙 1.3 设置字符集参数1.4 设置时区和时间&#xff08;可选&#xff09;关闭swap交换内存1.5 关闭RemoveIPC1.6 关闭HISTORY记录 2. 容器安装2. 1支持的架构和操作系统版本2…...

数据可视化大屏人员停留系统的开发实录(默认加载条件筛选、单击加载、自动刷新加载、异步加载数据)

项目需求 录入进入房间的相关数据&#xff1b;从进入时间开始计时&#xff0c;计算滞留房间的时间&#xff1b;定时刷新数据&#xff0c;超过30分钟的人数&#xff0c;进行红色告警&#xff1b; 实现流程 为了完整地实现上述需求&#xff0c;我们可以按照以下步骤开发&#…...

【Linux】-关于调试器gdb的介绍和使用

作者&#xff1a;小树苗渴望变成参天大树 作者宣言&#xff1a;认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; 文章目录 前言一、Linux中的debug和release二、gdb的使用**1.进入调试****2.显示代码*…...

项目开发经验

hadoop 1.namenode中有专门的工作线程池用于处理与datanode的心跳信号 dfs.namenode.handler.count20 * log2(Clust 2.编辑日志存储路径 dfs.namenode.edits.dir 设置与镜像文件存储路径 dfs.namenode分开存放&#xff0c;可以达到提高并发 3.yarn参数调优&#xff0c;单个服…...

STM32——05-按键、时钟控制、中断复位 点亮LED灯

如何点亮一颗LED灯 编程实现点灯 常用的 GPIO HAL 库函数&#xff1a; void HAL_GPIO_Init ( GPIO_TypeDef * GPIOx , GPIO_InitTypeDef * GPIO_Init ); void HAL_GPIO_WritePin ( GPIO_TypeDef * GPIOx , uint16_t GPIO_Pin , GPIO_PinState PinState ); void HAL_GPIO_Togg…...

VBA下载二进制文件,文本读写

这里使用了vba如下两个对象&#xff1a; Microsoft.XMLHTTP&#xff1a;文件读写&#xff0c;可读写二进制&#xff0c;可指定编码,对于utf-8编码文本文件使用FSO的TextStream对象打开&#xff0c;读取到的内容可能会出现乱码&#xff0c;可以使用该对象打开;前期绑定添加引用…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

Vue3 PC端 UI组件库我更推荐Naive UI

一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用&#xff0c;前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率&#xff0c;还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库&#xff08;Naive UI、Element …...