与前面提到的数据结构相同,队列中的数据也呈线性排列。虽然与栈有些类似,但队列中添加和删除数据的操做分别是在两端进行的,就和队列这个名字同样,把它想象成排成一队的人更容易理解。在队列中,处理老是从第一名开始日后进行,而新来的人只能排在队尾。算法
如上就是队列的概念图,如今队列中只有数据 Blue。往队列中添加数据时,数据被加在最上面。数组
而后,队列中添加了数据 Green。往队列中添加数据的操做叫做入队。数据结构
紧接着,数据 Red 也入队了。并发
从队列中取出(删除)数据时,是从最下面,也就是最先入队的数据开始的,即 Blue。从队列中删除数据的操做叫做出队。this
若是再进行一次出队操做,取出的就是 Green 了。code
像队列这种最早进去的数据最早被取来,即先进先出的结构,咱们称为 First In First Out,简称 FIFO。blog
与栈相似,队列中能够操做数据的位置也有必定的限制。在栈中,数据的添加和删除都在同一端进行,而在队列中则分别是在两端进行的。队列也不能直接访问位于中间的数据,必须经过出队操做将目标数据变成首位后才能访问。队列
介绍完队列的基本知识后,接下来举一个例子,好比生活中常见的排队买票。ci
队列这个概念很是好理解,你能够把它想象成排队买票,先来的先买,后来的人只能站末尾,不容许插队,先进者先出,这就是典型的队列。get
上一篇讲到栈只支持两个基本操做:入栈和出栈。队列跟栈很是类似,支持的操做也颇有限,最基本的操做也是两个:入队,放一个数据到队列尾部;出队,从队列头部取一个元素。
因此,队列跟栈同样,也是一种操做受限的线性表数据结构,队列的概念很好理解,基本操做也很容易掌握。做为一种很是基础的数据结构,队列的应用也很是普遍,特别是一些具备某些额外特性的队列,好比循环队列、阻塞队列、并发队列。
看到这里,相信你已经对队列有了初步的理解,队列主要包含两个操做,入队和出队。光理解还不够,咱们还要动手去实现队列,接下来让咱们来看一看如何用代码实现一个队列。
跟栈同样,队列能够用数组来实现,也能够用链表来实现。用数组实现的栈叫做顺序栈,用链表实现的栈叫做链式栈。一样,用数组实现的队列叫做顺序队列,用链表实现的队列叫做链式队列。
首先来看下用数组实现的队列是怎么样的,其实现以下图所示:
那么我先用 Java 语言来实现下顺序队列,代码以下:
/** * 基于数组实现的顺序队列 * * @author wupx * @date 2020/02/13 */ public class ArrayQueue { private String[] items; /** * 数组大小 */ private int n = 0; /** * 队头下标 */ private int head = 0; /** * 队尾下标 */ private int tail = 0; /** * 申请一个大小为 capacity 的数组 * * @param capacity */ public ArrayQueue(int capacity) { items = new String[capacity]; n = capacity; } /** * 入队 * * @param item * @return */ public boolean enqueue(String item) { // 若是 tail == n 表示队列已经满了 if (tail == n) { return false; } items[tail] = item; ++tail; return true; } /** * 出队 * * @return */ public String dequeue() { // 若是 head == tail 表示队列为空 if (head == tail) { return null; } String ret = items[head]; ++head; return ret; } }
另一种就是链式队列,它的实现以下图所示:
再用链表去实现队列,代码以下:
/** * 基于链表实现的链式队列 * * @author wupx * @date 2020/02/13 */ public class LinkedListQueue { /** * 队头 */ private Node head = null; /** * 队尾 */ private Node tail = null; /** * 入队 * * @param value */ public void enqueue(String value) { if (tail == null) { Node newNode = new Node(value, null); head = newNode; tail = newNode; } else { tail.next = new Node(value, null); tail = tail.next; } } /** * 出队 * * @return */ public String dequeue() { if (head == null) { return null; } String value = head.data; head = head.next; if (head == null) { tail = null; } return value; } public void printAll() { Node p = head; while (p != null) { System.out.print(p.data + " "); p = p.next; } System.out.println(); } private static class Node { private String data; private Node next; public Node(String data, Node next) { this.data = data; this.next = next; } public String getData() { return data; } } }
到此,咱们就分别实现了基于数组和链表的队列,你们能够本身实现下。
队列还有不少扩展,好比循环队列、阻塞队列、并发队列等,将在之后的文章中进行介绍。
这篇主要讲了一种跟栈很类似的数据结构-队列,也是一种线性逻辑结构。
队列遵循先进先出(FIFO)的原则,主要的两个操做是入队和出队。队列既能够用数组来实现,也能够用链表来实现。用数组实现的叫顺序队列,用链表实现的叫链式队列。
参考
《个人第一本算法书》