队列/栈基本原理

简介: 本文介绍栈和队列的基本原理。二者均为操作受限的数据结构:队列仅能在队尾入队、队头出队,遵循“先进先出”(FIFO);栈则只允许在栈顶进行插入和删除,遵循“先进后出”(FILO)。底层多用数组或链表实现。

❗前置知识
阅读本文前,你需要先学习:
● 链表(链式存储)基础
● 数组(顺序存储)基础
计算机的两种存储方式,顺序存储(数组)和链式存储(链表)都讲完了,之后的所有数据结构都是基于这两种存储方式之上玩花活。
本文讲解队列和栈的基本原理,后面的文章会讲解如何用代码具体实现。
先说概念吧,其实队列和栈都是「操作受限」的数据结构。说它操作受限,主要是和基本的数组和链表相比,它们提供的 API 是不完整的。
比方说我们前面实现的数组和链表,增删查改的 API 都实现过了,你可以对任意一个索引元素进行增删查改,只要索引不越界,就随便你。
但是对于队列和栈,它们的操作是受限的:队列只能在一端插入元素,另一端删除元素;栈只能在某一端插入和删除元素。
形象地说,队列只允许在队尾插入元素,在队头删除元素,栈只允许在栈顶插入元素,从栈顶删除元素:
队列就像排队买票,先来的先买,后来的后买;栈就像一摞盘子,最先放的压在最下面,最后放的留在最上面,拿的时候也是最上面的先被拿走。所以我们常说,队列是一种「先进先出 FIFO」的数据结构,栈是一种「先进后出 FILO」的数据结构,就是这个道理。
当然,这个图中把栈竖着画,队列横着画,只是为了更形象,但实际上它们底层都是数组和链表实现的,后面会讲到。这两种数据结构的基本 API 如下:
// 队列的基本 API
class MyQueue {
// 向队尾插入元素,时间复杂度 O(1)
void push(E e);

// 从队头删除元素,时间复杂度 O(1)
E pop();

// 查看队头元素,时间复杂度 O(1)
E peek();

// 返回队列中的元素个数,时间复杂度 O(1)
int size();

}

// 栈的基本 API
class MyStack {
// 向栈顶插入元素,时间复杂度 O(1)
void push(E e);

// 从栈顶删除元素,时间复杂度 O(1)
E pop();

// 查看栈顶元素,时间复杂度 O(1)
E peek();

// 返回栈中的元素个数,时间复杂度 O(1)
int size();

}
不同编程语言中,队列和栈提供的方法名称可能不一样,但每个方法的效果肯定是一样的。

相关文章
|
1天前
|
存储 缓存 算法
学习数据结构和算法的框架思维
本文系统梳理数据结构与算法核心思想:所有数据结构本质为数组或链表的变形,基本操作均为遍历与访问;算法本质是穷举,关键在于“无遗漏”和“无冗余”。掌握框架思维,方能以不变应万变,高效刷题。
学习数据结构和算法的框架思维
|
1天前
|
存储 数据可视化 Java
用拉链法实现哈希表
本文详解哈希表中拉链法的实现原理,通过简化版与完整版Java代码,介绍如何用链表解决哈希冲突,支持泛型、动态扩容及增删查改操作,帮助深入理解哈希表底层机制。
|
1天前
|
存储 缓存 算法
哈希表核心原理
哈希表不等于Map。Map是键值映射的抽象接口,哈希表(如HashMap)是其基于数组和哈希函数的具体实现之一。增删查改O(1)的性能依赖于哈希函数效率与冲突处理,而Map其他实现(如TreeMap)复杂度可能为O(logN)。需注意哈希冲突、扩容、负载因子及key不可变性等核心问题。
|
1天前
|
存储 算法 Java
动态数组代码实现
本文详解动态数组的底层实现,涵盖自动扩缩容、索引越界检查与内存泄漏防范三大关键点,结合Java代码演示增删查改操作及扩容机制,帮助理解数据结构设计原理。
|
1天前
|
算法 数据可视化
二叉树的递归/层序遍历 递归遍历(DFS)
本文详解二叉树的遍历框架,涵盖递归遍历的固定访问顺序及前、中、后序的本质区别——即代码在递归函数中的位置不同所致。同时深入讲解层序遍历(BFS)的三种实现方式,适用于不同场景,尤其适合求最短路径问题;而DFS则因结构天然适合搜索所有路径。通过实例对比,阐明BFS与DFS的应用偏好及原理依据。
二叉树的递归/层序遍历 递归遍历(DFS)
|
1天前
|
人工智能 Java 程序员
JavaSE进阶
本文介绍了Java开发入门的完整流程,涵盖JDK安装、IDEA配置与使用、第一个Java程序的创建与运行。内容包括项目搭建、模块与包的创建、代码注释规范、常用快捷键及通义灵码插件安装等实用技巧,并结合真实工作场景给出操作建议,适合初学者快速掌握开发环境配置与基础编码技能。(239字)
JavaSE进阶
多叉树的递归/层序遍历
多叉树是二叉树的扩展,每个节点可有多个子节点。遍历方式类似:递归遍历无中序概念;层序遍历用队列实现,可记录深度或适配加权边,代码结构与二叉树一致,仅子节点处理由左右变为列表遍历。
|
1天前
|
存储 算法 Java
链表(链式存储)基本原理
本文深入讲解链表数据结构,对比力扣中的单链表与编程语言标准库中的双链表差异,涵盖泛型支持与双向指针特性。剖析链表内存分散存储、动态扩容的优势及索引访问的局限性,并通过代码详解单/双链表的增删查改操作,引入虚拟头结点优化边界处理,帮助读者掌握链表核心原理与实现技巧。
|
1天前
|
存储 Java API
数组(顺序存储)基本原理
本章讲解数组的底层原理,区分静态数组与动态数组。静态数组是连续内存空间,支持O(1)随机访问,但增删效率低;动态数组基于静态数组封装,提供自动扩容和常用API,使用更便捷。我们将从零实现一个动态数组,掌握其增删查改机制,理解常见数据结构的底层逻辑,为后续学习栈、队列、哈希表打下基础。
|
1天前
|
算法 Python
双端队列(Deque)原理及实现
双端队列支持在队头和队尾高效地插入、删除元素,时间复杂度均为O(1)。相比标准队列的“先进先出”,它更灵活,类似两端可进出的过街天桥。可用链表或环形数组实现,常用于算法题中模拟栈或队列。