前言

阅读此篇之前,强烈建议先仔细阅读上一篇 图解数据结构:数组和单链表 ,会有事半功倍的效果,并且此篇的代码,基本上是复用上一篇的实现。

上一篇主要讲解了数组和链表这两种线性结构的特点、区别、时间复杂度分析等。对数组和链表的划分,实际上是物理结构(存储结构)的划分。
物理结构有两种基本的结构:顺序存储结构、链式存储结构。而本篇所讲解的栈和队列属于逻辑结构上的划分。逻辑结构分为线性结构、非线性结构。

  • 线性结构:有且仅有一个开始节点和一个终端节点,每个节点最多只有一个直接前驱和一个直接后继。代表结构:栈、队列
  • 非线性结构:一个节点可能有多个直接前驱和多个直接后继。代表结构:树、图

本篇主要讲解栈和队列的特点、区别,以及用数组和链表分别实现栈和队列。

堆栈(英语:stack)又称为栈或堆叠,是计算机科学中的一种抽象数据类型,只允许在有序的线性数据集合的一端(称为堆栈顶端,英语:top)进行加入数据(英语:push)和移除数据(英语:pop)的运算。因而按照后进先出(LIFO, Last In First Out)的原理运作。

栈的主要特点就是LIFO(Last In First Out,后进先出),并且程序只能操作栈的一端,被操作的一端叫做栈顶(Top)。所以栈的使用非常简单,但是实现的功能却非常强大。
栈的主要操作有两个个:入栈(push)、出栈(pop)。

入栈(push)


如图所示,栈就像一个瓶子,只有一个口。三个元素A、B、C先后入栈,先入栈的放在底部,后入栈的放在上面。

出栈(pop)


根据图示,栈顶的元素最先出栈。这与入栈的顺序刚好相反,入栈顺序是A->B->C,出栈顺序是C->B->A。也就是说:栈是LIFO(Last In First Out,后进先出的)。
看似简单的栈,应用十分广泛。操作系统的函数调用、各类编辑器的撤销操作的实现都离不开栈。

栈有两种实现方式:顺序栈链式栈

顺序栈

顺序栈用数组实现,基于上一篇 图解数据结构:数组和单链表 ,我们实现了动态数组,实际上用数组实现栈,就是将数组的增、删操作限制在头部或者尾部,即只能在数组的一端操作元素,就成了顺序栈,复用上一篇的代码,实现顺序栈就很简单了。

// 动态数组实现顺序栈
public class ArrayStack<E> {// 此处ArrayList为上一篇博客所实现的private ArrayList<E> list;public ArrayStack() {list = new ArrayList();}/*** 入栈* @param e* @return*/public E push(E e) {list.add(e);return e;}/*** 出栈* @return*/public E pop() {return list.remove();}/*** 查看栈顶元素* @return*/public E peek() {return list.get(list.size() - 1);}
}

注意:pop()peek()方法都能返回栈顶元素,pop()方法会删除栈顶元素,也就是出栈。而peek()方法仅仅是查看栈顶元素,不会删除栈顶元素。
以上几个方法的时间复杂度在动态数组ArrayList中都已经分析过了,此处不再赘述。
完整代码下载地址:
Github:ArrayStack.java

链式栈

链式栈是用链表实现栈,也就是上一篇实现的LinkedList。由于复用了上一篇的代码,所以实现起来也非常简单,基本上只需要把顺序栈中ArrayList换成LinkedList就可以了。

队列

队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作。
队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。

与栈(stack)不同的是,队列是FIFO(First In First Out,先进先出),进入队列的一端叫尾部(rear),出队列的一端叫头部(front)。队列的主要操作也有两个:入队(offer)、出队(poll)

入队


从图中可以看到,A、B、C三个元素都是从队尾(rear)进入,就像现实生活中的排队,先来的就排在前面。

出队


从图中可以看出,出队的顺序是A->B->C,也就是入队的顺序,即说明了队列是遵循FIFO的。队列的引用也十分广泛,锁的实现、生产者-消费者模型等都离不开队列。

队列也有两种实现方式:顺序队列链式队列

顺序队列

顺序队列用数组实现,基于上一篇 图解数据结构:数组和单链表 ,我们实现了动态数组,用数组实现队列,就是将数组的增操作限制在尾部,删操作限制在头部,即分别只能在数组的一端操作元素,就成了顺序队列,复用上一篇的代码。

public class ArrayQueue<E> {// 此处ArrayList为上一篇博客所实现的private ArrayList<E> list;public ArrayQueue() {list = new ArrayList();}/*** 出队* @param e*/public void offer(E e) {list.add(e);}/*** 入队* @return*/public E poll() {return list.remove(0);}/*** 查看队列头部元素* @return*/public E peek() {return list.get(0);}}

注意:poll()peek()方法都能返回队列头部元素,poll()方法会删除队列头部元素,也就是出队。而peek()方法仅仅是查看队列头部元素,不会删除队列头部元素。
完整代码下载地址:
Github:ArrayQueue.java

链式队列

链式队列是用链表实现队列,也就是上一篇实现的LinkedList。由于复用了上一篇的代码,所以实现起来也非常简单,基本上只需要把顺序队列中ArrayList换成LinkedList就可以了。

总结

对于栈和队列的简单实现,其实上一篇就已经实现过了,所以本篇的重点是理解栈和队列的工作方式、结构区别、使用区别等。栈和队列是比较简单的线性结构,但是简单不代表用得少。实际上栈和队列的应用非常广泛,理解其工作原理,是使用好栈和队列的第一步,也是最重要的一步。

图解数据结构:栈和队列相关推荐

  1. 数据结构栈和队列_使您的列表更上一层楼:链接列表和队列数据结构

    数据结构栈和队列 When you want to store several elements somewhere in a program, the go-to data type is an a ...

  2. 数据结构栈与队列的应用之汽车轮渡问题——自己的一些理解

    本题摘自王道数据结构栈与队列的应用的课后题,题目如下: 某汽车轮渡口,过江渡船每次能载10辆汽车过江.过江车辆分为客车类和货车类,上渡船有如下规定:同类车先到先上船,客车先于货车上船,且每上4辆客车, ...

  3. 数据结构——栈与队列相关题目

    数据结构--栈与队列相关题目 232. 用栈实现队列 思路 225. 用队列实现栈 1.两个队列实现栈 2.一个队列实现栈 20. 有效的括号 思路 1047. 删除字符串中的所有相邻重复项 思路 1 ...

  4. 大话数据结构-栈与队列

    文章知识点来至于大话数据结构里边章节知识, 这篇主要介绍栈与队列在计算机中存储形式, 以及在某些算法领域中对栈和队列的相关应用.章节最后介绍了著名的逆波兰表达式, 以及通过算法来实现该表达式的运算过程 ...

  5. 【数据结构基础】线性数据结构——栈和队列的总结及封装(C和java)

    前言 数据结构,一门数据处理的艺术,精巧的结构在一个又一个算法下发挥着他们无与伦比的高效和精密之美,在为信息技术打下坚实地基的同时,也令无数开发者和探索者为之着迷. 也因如此,它作为博主大二上学期最重 ...

  6. 第十章 基本数据结构——栈和队列

    摘要 本章介绍了几种基本的数据结构,包括栈.队列.链表以及有根树,讨论了使用指针的简单数据结构来表示动态集合.本章的内容对于学过数据结构的人来说,没有什么难处,简单的总结一下. 1.栈和队列 栈和队列 ...

  7. 数据结构——栈与队列操作(用栈模拟队列)

    [栈与队列操作] 问题描述:假设有两个长度相同的栈 S1,S2,已知以下入栈.出栈.判栈满和判栈空操作: void Push(S,x); Elemtype Pop(S); bool StackFull ...

  8. 【数据结构-栈和队列】详解栈和队列(代码+STL+原理)

    一.栈的应用 栈是一种先进后出(FILO)的数据结构 1.1 栈的操作实现 清空(clear): // 栈的清空操作就是把栈顶top置为-1 void clear(){top=-1; } // 清空栈 ...

  9. 算法与数据结构 -- 栈与队列(四)

    栈与队列定义了数据的操作 一.栈 栈是一种先入先出的数据结构.可以用顺序表实现,也可以用链表实现 栈操作 判断是否为空 压栈.入栈push 出栈 pop 返回栈顶元素 peek 栈的元素个数 # co ...

  10. 六十二、数据结构栈和队列的相互实现

    @Author:Runsen 编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化. ---- Runsen 算法,一门既不容易入门,也不容易精通的学问. 栈和队列都是用来保存数 ...

最新文章

  1. 51nod1008 N的阶乘 mod P(水题)
  2. oracle存储查询出来的值_技术分享|浅析ORACLE数据库物理体系结构及其对应优化策略...
  3. 乐视TV做电视 “自杀”还是“猎杀”
  4. 北京理工大学信息安全与对抗竞赛----crackme02分析
  5. WatchOS系统开发大全(7)-WKInterfaceImage
  6. upplemental Logging
  7. python笔记之matplotlib.pyplot曲线平滑自定义函数:smooth_curv()
  8. 苹果Mac 3D 建模渲染软件:Vectorworks
  9. 研磨设计模式--外观模式
  10. struts2的ActionSupport
  11. STM32 使用SPI读写FLASH(W25Q64型号)
  12. 校园网IPv6免流上网
  13. python批量改变图像大小
  14. 淘宝卖家中心打开淘宝客推广网页空白
  15. 保研面试/考研复试高等数学问题整理
  16. 写作分册王诚pdf_后王诚时代|老铁们,管综写作还能跟谁?
  17. Ubuntu18.04/20.04 上微信中文显示为方块状乱码的解决方案( Deepin-Wechat )
  18. Redis相关知识点
  19. 前端工程师用代码制作特效,七夕情人节成功表白女神,终于摆脱单身
  20. javaScript 美化radio

热门文章

  1. 【转】区块链中VRF的应用及原理解析
  2. 微型计算机赛睿寒冰5评测,赛睿Arctis寒冰5耳机2019款评测:小升级但依旧诚意满满...
  3. 看漫画也能学Java?大佬亲自带你进入Java的世界
  4. split( )与split( ,-1)的区别
  5. 鸿蒙OS笔记本电脑,弃用Windows!搭载鸿蒙的笔记本电脑要来了!但首发竟不在国内?...
  6. 材料数据科学:描述符和机器学习
  7. 永久免费H5直播点播播放器SkeyeWebPlayer.js实现webrtc流播放
  8. 【转】NetworkManager nmcli学习(热点)
  9. 分治法 第3关:找出数组中第 k 个小的元素
  10. BAT都着力发展消费金融,相比之下有什么不同?