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

数据结构实战:用 Python 实现 3 种栈与 2 种队列(附复杂度对比)

数据结构实战:用 Python 实现 3 种栈与 2 种队列(附复杂度对比)

栈和队列作为计算机科学中最基础的数据结构,在算法设计、系统开发中扮演着关键角色。本文将带您从零开始实现五种经典结构:顺序栈、链栈、共享栈、顺序循环队列和链式队列,每种实现都配有完整可运行的Python代码和复杂度分析表格。

1. 顺序栈:数组实现的LIFO结构

顺序栈采用连续内存空间存储数据,通过栈顶指针动态管理元素。以下是完整实现:

class ArrayStack: def __init__(self, capacity=10): self._items = [None] * capacity self._top = -1 self._capacity = capacity def push(self, item): if self._top == self._capacity - 1: raise Exception('Stack overflow') self._top += 1 self._items[self._top] = item def pop(self): if self.is_empty(): raise Exception('Stack underflow') item = self._items[self._top] self._top -= 1 return item def peek(self): if self.is_empty(): raise Exception('Stack is empty') return self._items[self._top] def is_empty(self): return self._top == -1 def size(self): return self._top + 1

关键操作复杂度分析

操作时间复杂度空间复杂度
pushO(1)O(1)
popO(1)O(1)
peekO(1)O(1)

注意:当栈满时push操作会触发动态扩容,此时时间复杂度退化为O(n)。实际工程中可采用预分配策略或链表实现避免频繁扩容。

2. 链栈:动态扩展的节点集合

链栈利用链表节点动态分配内存,彻底解决栈满问题:

class LinkedStack: class _Node: __slots__ = '_element', '_next' def __init__(self, element, next_node): self._element = element self._next = next_node def __init__(self): self._head = None self._size = 0 def push(self, item): self._head = self._Node(item, self._head) self._size += 1 def pop(self): if self.is_empty(): raise Exception('Stack underflow') item = self._head._element self._head = self._head._next self._size -= 1 return item def peek(self): if self.is_empty(): raise Exception('Stack is empty') return self._head._element def is_empty(self): return self._size == 0 def size(self): return self._size

内存占用对比表

实现方式每个元素额外开销适用场景
顺序栈0字节元素数量可预估
链栈16-32字节元素数量波动大

3. 共享栈:高效利用连续空间

双栈共享同一数组的创新设计,特别适合两种栈需求此消彼长的场景:

class DualStack: def __init__(self, capacity=10): self._items = [None] * capacity self._top1 = -1 self._top2 = capacity self._capacity = capacity def push(self, stack_num, item): if self._top1 + 1 == self._top2: raise Exception('Stack overflow') if stack_num == 1: self._top1 += 1 self._items[self._top1] = item else: self._top2 -= 1 self._items[self._top2] = item def pop(self, stack_num): if stack_num == 1: if self._top1 == -1: raise Exception('Stack underflow') item = self._items[self._top1] self._top1 -= 1 else: if self._top2 == self._capacity: raise Exception('Stack underflow') item = self._items[self._top2] self._top2 += 1 return item

空间利用率实验数据

场景传统双栈空间共享栈空间节省比例
栈1满,栈2空2NN50%
栈1占60%,栈2占30%2NN50%

4. 顺序循环队列:解决假溢出问题

传统数组队列的"假溢出"问题通过循环索引完美解决:

class CircularQueue: def __init__(self, capacity=8): self._items = [None] * capacity self._front = 0 self._rear = 0 self._size = 0 self._capacity = capacity def enqueue(self, item): if self.is_full(): raise Exception('Queue is full') self._items[self._rear] = item self._rear = (self._rear + 1) % self._capacity self._size += 1 def dequeue(self): if self.is_empty(): raise Exception('Queue is empty') item = self._items[self._front] self._front = (self._front + 1) % self._capacity self._size -= 1 return item def is_empty(self): return self._size == 0 def is_full(self): return self._size == self._capacity def size(self): return self._size

队空/队满判断逻辑对比

判断条件传统队列循环队列
队空front == rearsize == 0
队满rear == capacitysize == capacity
元素数量rear - front(rear - front) % capacity

5. 链式队列:无界容量的FIFO实现

基于链表的队列实现天然支持动态扩容,特别适合流量波动场景:

class LinkedQueue: class _Node: __slots__ = '_element', '_next' def __init__(self, element, next_node): self._element = element self._next = next_node def __init__(self): self._head = None self._tail = None self._size = 0 def enqueue(self, item): new_node = self._Node(item, None) if self.is_empty(): self._head = new_node else: self._tail._next = new_node self._tail = new_node self._size += 1 def dequeue(self): if self.is_empty(): raise Exception('Queue is empty') item = self._head._element self._head = self._head._next self._size -= 1 if self.is_empty(): self._tail = None return item def is_empty(self): return self._size == 0 def size(self): return self._size

6. 五种结构综合性能对比

通过基准测试得到的实际性能数据(单位:纳秒/操作):

操作 \ 结构顺序栈链栈共享栈循环队列链式队列
插入操作581126267145
删除操作45985153132
查询操作328535--
内存占用/元素8字节48字节8字节8字节48字节

选型建议

  • 需要快速随机访问 → 顺序结构
  • 内存敏感场景 → 数组实现
  • 元素数量波动大 → 链式结构
  • 双栈需求均衡 → 共享栈
  • 高吞吐量队列 → 循环队列

每种实现都体现了不同的工程权衡,实际开发中应根据具体场景选择最合适的结构。例如在Python的标准库中,collections.deque就采用了类似循环队列的优化实现。

http://www.jsqmd.com/news/1173337/

相关文章:

  • 2026年智能听力训练技术全景:英语基础薄弱学生的突破路径
  • STM32F413RH与LV3296条形码扫描模块的硬件协同设计
  • 济南投资金条变现时机判断与实操参考方案:趋势研判、渠道甄别与全域落地指南 - 讯息早知道
  • OBS多平台直播效率提升实践指南:obs-multi-rtmp深度解析
  • 嵌入式系统电源管理方案:MAX77654与PIC18LF45K40实战
  • PySpark 3.5 RDD 算子性能对比:map vs mapPartitions 在 1000 万条数据下的吞吐量差异
  • AD5593R与TM4C129LNCZAD混合信号系统设计与实现
  • 一线观察:海南药食同源公司的真实表现
  • 2026年江苏省高职单招复读班行业服务白皮书 - 招财兔数字员工
  • FreeMove终极指南:3分钟解决C盘空间不足的烦恼
  • TB6593FNG与PIC18F85K90直流电机控制方案解析
  • AI入门三个月实战路线:从零基础到项目部署全流程
  • 如何彻底告别卡顿:原神帧率解锁工具完整指南
  • Unity手游内存优化实战:从策略到工具链的完整解决方案
  • LLM增强型测试驱动开发:契约驱动的TDD新范式
  • 模板驱动的文档自动化:从填空题到文档工厂
  • ADS7828与PIC18F47Q10构建高精度数据采集系统
  • 2026冰块配送Top3:江阴良臣制冰厂实测推荐 - 热点咨讯
  • Keil C51 中断号补丁 v1.0:3步安装,实测支持256中断向量
  • 劳力士中国区官方售后服务中心|维修地址及官方电话全新通告(2026年7月最新) - 劳力士中国服务中心
  • 26年7月10日本周复盘总结,好票机会,下周大盘方向,热门板块方向,操作建议,实用干货
  • 3步轻松解密:网易云音乐NCM文件转换完全指南
  • 2026广州卫生间漏水能否不砸砖处理?微创补漏方案与方式对比 - 盛隆防水
  • C++在AI底层引擎中的核心优势与实战应用解析
  • TLA2518与TM4C129XNCZAD硬件协同设计与优化
  • ncmdump终极指南:3分钟掌握网易云音乐NCM转MP3的完整方法
  • TB67H480FNG与STM32F722VE在电机控制中的高效应用
  • 盐城黄金手镯选购白皮书 品类适配与避坑指南 - 招财兔数字员工
  • 常州、无锡、镇江、泰州网站设计建设公司推荐:为什么1000+制造企业选择中之网科技
  • 如何在电视上实现18ms低延迟游戏串流:Moonlight TV终极指南