什么是队列?

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

什么是队列?
与前⾯提到的相同,队列中的数据也呈线性排列。

虽然与有些相似,但队列中添加和删除数据的操作分别是在两端进⾏的,就和队列这个名字⼀样,把它想象成排成⼀队的⼈更容易理解。

在队列中,处理总是从第⼀名开始往后进⾏,⽽新来的⼈只能排在队尾。

队列是什么?
如上就是队列的概念图,现在队列中只有数据 Blue。

往队列中添加数据时,数据被加在最上⾯。

然后,队列中添加了数据 Green。

往队列中添加数据的操作叫作⼊队。

紧接着,数据 Red 也⼊队了。

从队列中取出(删除)数据时,是从最下⾯,也就是最早⼊队的数据开始的,即 Blue。

从队列中删除数据的操作叫作出队。

如果再进⾏⼀次出队操作,取出的就是 Green 了。

像队列这种最先进去的数据最先被取来,即先进先出的结构,我们称为 First In First Out,简称 FIFO。

与栈类似,队列中可以操作数据的位置也有⼀定的限制。

在栈中,数据的添加和删除都在同⼀端进⾏,⽽在队列中则分别是在两端进⾏的。

队列也不能直接访问位于中间的数据,必须通过出队操作将⽬标数据变成⾸位后才能访问。

介绍完队列的基本知识后,接下来举⼀个例⼦,⽐如⽣活中常见的排队买票。

如何理解队列?
队列这个概念⾮常好理解,你可以把它想象成排队买票,先来的先买,后来的⼈只能站末尾,不允许插队,先进者先出,这就是典型的队列。

排队买票
上⼀篇讲到栈只⽀持两个基本操作:⼊栈和出栈。

队列跟栈⾮常相似,⽀持的操作也很有限,最基本的操作也是两个:⼊队,放⼀个数据到队列尾部;出队,从队列头部取⼀个元素。

所以,队列跟栈⼀样,也是⼀种操作受限的线性表数据结构,队列的概念很好理解,基本操作也很容易掌握。

作为⼀种⾮常基础的数据结构,队列的应⽤也⾮常⼴泛,特别是⼀些具有某些额外特性的队列,⽐如循环队列、阻塞队列、并发队列。

队列的实现
看到这⾥,相信你已经对队列有了初步的理解,队列主要包含两个操作,⼊队和出队。

光理解还不够,我们还要动⼿去实现队列,接下来让我们来看⼀看如何⽤代码实现⼀个队列。

跟栈⼀样,队列可以⽤数组来实现,也可以⽤链表来实现。

⽤数组实现的栈叫作顺序栈,⽤链表实现的栈叫作链式栈。

同样,⽤数组实现的队列叫作顺序队列,⽤链表实现的队列叫作链式队列。

⾸先来看下⽤数组实现的队列是怎么样的,其实现如下图所⽰:
顺序队列
那么我先⽤ 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)的原则,主要的两个操作是⼊队和出队。

队列既可以⽤数组来实现,也可以⽤链表来实现。

⽤数组实现的叫顺序队列,⽤链表实现的叫链式队列。

参考
《我的第⼀本算法书》。

相关文档
最新文档