栈和队列(数据结构刷题)[一]-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.思路 三、关于面试考察栈里面的元素在内存中是连续分布的么? 前言 提到栈和队列,大家可能对它们的了解只停留在表面,再深入一点,好像知道又好像不知道的感觉。本文我将从底层实…...
【备战秋招】JAVA集合
集合 前言 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象 的操作,就要 对对象进行存储。 另一方面,使用Array存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多…...
setState详解
this. setState( [partialState], [callback]) 1.[partialState] :支持部分状态更改 this, setState({ x:100 //不论总共有多少状态,我们只修改了x,其余的状态不动 });callback :在状态更改/视图更新完毕后触发执行,也可以说只要执行了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平台…...
七、进程程序替换
文章目录 一、进程程序替换(一)概念(二)为什么程序替换(三)程序替换的原理(四)如何进行程序替换1. execl2. 引入进程创建——子进程执行程序替换,会不会影响父进程呢? &…...
C++核心编程——详解运算符重载
文章目录💬 一.运算符重载基础知识①基本概念②运算符重载的规则③运算符重载形式④运算符重载建议 二.常用运算符重载①左移(<<)和右移(>>)运算符重载1️⃣重载后函数参数是什么?2️⃣重载的函数返回类型是什么?3️⃣重载为哪种…...
2023年前端面试汇总-CSS
1. CSS基础 1.1. CSS选择器及其优先级 对于选择器的优先级: 1. 标签选择器、伪元素选择器:1; 2. 类选择器、伪类选择器、属性选择器:10; 3. id 选择器:100; 4. 内联样式:1000&a…...
Java调用Pytorch实现以图搜图(附源码)
Java调用Pytorch实现以图搜图 设计技术栈: 1、ElasticSearch环境; 2、Python运行环境(如果事先没有pytorch模型时,可以用python脚本创建模型); 1、运行效果 2、创建模型(有则可以跳过…...
【EasyX】实时时钟
目录 实时时钟1. 绘制静态秒针2. 秒针的转动3. 根据实际时间转动4. 添加时针和分针5. 添加表盘刻度 实时时钟 本博客介绍利用EasyX实现一个实时钟表的小程序,同时学习时间函数的使用。 本文源码可从github获取 1. 绘制静态秒针 第一步定义钟表的中心坐标center&a…...
基于XC7Z100的PCIe采集卡(GMSL FMC采集卡)
GMSL 图像采集卡 特性 ● PCIe Gen2.0 X8 总线; ● 支持V4L2调用; ● 1路CAN接口; ● 6路/12路 GMSL1/2摄像头输入,最高可达8MP; ● 2路可定义相机同步触发输入/输出; 优势 ● 采用PCIe主卡与FMC子…...
Kibana:使用 Kibana 自带数据进行可视化(一)
在今天的练习中,我们将使用 Kibana 自带的数据来进行一些可视化的展示。希望对刚开始使用 Kibana 的用户有所帮助。 前提条件 如果你还没有安装好自己的 Elastic Stack,你可以参考如下的视频来开启 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 是一个透明的、自下而上替代自上而下的多元网络,旨在克服当前生态系统的局限性,实现去中心化社会。 aVive:一个基于 SBT 和市场的 deSoc,它使 dapps 能够与分散的位置 oracle 和 SBT 关系进行互操作。您的主权社交网络元宇宙…...
openGauss5.0之学习环境 Docker安装
文章目录 0.前言1. 准备软硬件安装环境1.1 软硬件环境要求1.2 修改操作系统配置1.2.1 关闭操作系统防火墙 1.3 设置字符集参数1.4 设置时区和时间(可选)关闭swap交换内存1.5 关闭RemoveIPC1.6 关闭HISTORY记录 2. 容器安装2. 1支持的架构和操作系统版本2…...
数据可视化大屏人员停留系统的开发实录(默认加载条件筛选、单击加载、自动刷新加载、异步加载数据)
项目需求 录入进入房间的相关数据;从进入时间开始计时,计算滞留房间的时间;定时刷新数据,超过30分钟的人数,进行红色告警; 实现流程 为了完整地实现上述需求,我们可以按照以下步骤开发&#…...
【Linux】-关于调试器gdb的介绍和使用
作者:小树苗渴望变成参天大树 作者宣言:认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! 文章目录 前言一、Linux中的debug和release二、gdb的使用**1.进入调试****2.显示代码*…...
项目开发经验
hadoop 1.namenode中有专门的工作线程池用于处理与datanode的心跳信号 dfs.namenode.handler.count20 * log2(Clust 2.编辑日志存储路径 dfs.namenode.edits.dir 设置与镜像文件存储路径 dfs.namenode分开存放,可以达到提高并发 3.yarn参数调优,单个服…...
STM32——05-按键、时钟控制、中断复位 点亮LED灯
如何点亮一颗LED灯 编程实现点灯 常用的 GPIO HAL 库函数: 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如下两个对象: Microsoft.XMLHTTP:文件读写,可读写二进制,可指定编码,对于utf-8编码文本文件使用FSO的TextStream对象打开,读取到的内容可能会出现乱码,可以使用该对象打开;前期绑定添加引用…...
Java入门第162课——HTML 基础语法与文档结构
1.1 Web 核心基础认知 1.1.1 Web 工作原理 Web 采用客户端 - 服务器(C/S) 架构,核心流程: 客户端(浏览器)通过 URL 向服务器发送请求; 服务器接收请求后处理,返回 HTML/CSS/JS 等资源; 浏览器解析资源,以图形化方式展示页面。 1.1.2 Web 相关技术分类 服务器端技术…...
MySQL分库分表的实现(二)--水平分表
本文介绍下使用Sharding-JDBC实现水平分表 Sharding-JDBC是轻量级的 java 框架,是增强版的 JDBC 驱动,使用Sharding-JDBC可以简化对分库分表之后数据相关操作。下面分别介绍下水平分表的方法。 1、准备好数据库和数据表 先创建一个course_db数据库,然…...
黑马点评-用JMeter测试缓存重建时,HTTP请求的响应结果的data为空
问题描述用JMeter测试缓存重建时,HTTP请求的响应结果的data为空解决方案1.未缓存预热(可能的问题1)“逻辑过期”方案通常用于极高并发的热点 Key。为了防止查数据库拖垮系统,我们默认这些热点数据一定是事先手动存入 Redis 的解决方法: 运行下面测试方法将"热点…...
Bash脚本学习
1、第一行#!/bin/bash,表示sh脚本默认按bash运行2、set ex #命令失败时立即退出;打印执行的每一条命令 set -o pipefail #管道中任何一个命令失败都算失败3、basepath$(cd "$(dirname "$0")" && pwd) #获取脚本所在路径一、…...
C++课后习题训练记录Day118
1.练习项目: 问题描述 小蓝最近在研究一种浮点数的表示方法:RR 格式。对于一个大于 0 的浮点数 dd,可以用 RR 格式的整数来表示。给定一个转换参数 nn,将浮点数转换为 RR 格式整数的做法是: 将浮点数乘以 2^n; 四舍…...
【路径规划】基于时空A星算法求解带时间约束的多机器人路径规划问题附matlab代码
✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…...
linux系统 Ventoy 制作U启
比起君子讷于言而敏于行,我更喜欢君子善于言且敏于行。 目录 1. 下载 Ventoy 2. 解压压缩包 3. 插入U盘并确认设备名 4. 安装Ventoy到U盘(会格式化U盘) 5. 复制ISO文件 6. 使用启动盘 Ventoy的优点 1. 下载 Ventoy wget https://github.com/v…...
Cosmos-Reason1-7B多场景部署案例:高校AI通识课+专业课双轨教学工具
Cosmos-Reason1-7B多场景部署案例:高校AI通识课专业课双轨教学工具 1. 引言:当AI推理遇上高校教学 高校教学正面临一个有趣挑战:既要让学生理解AI技术原理,又要让他们实际运用AI解决专业问题。传统教学工具要么太理论化࿰…...
Chord视觉定位模型效果展示:支持模糊描述‘看起来像椅子的东西’准确定位
Chord视觉定位模型效果展示:支持模糊描述‘看起来像椅子的东西’准确定位 1. 项目简介 想象一下,你正在整理手机里上千张照片,想找出所有“看起来像椅子的东西”——可能是公园的长椅、家里的餐椅、甚至是一个形状奇特的石头。传统方法需要…...
java+vue+springboot开题报告 基于视频的运动目标分割算法研究
目录研究背景与意义研究内容与方法预期成果创新点分析进度计划关键技术示例(代码片段)项目技术支持可定制开发之功能亮点源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作研究背景与意义 视频中的运动目标分割是计算机…...
