队列 Queue

概述

队列(Queue)是一个先进先出(FIFO:First In First Out)的有序表,可以由数组或者链表实现。
由链表实现的队列和List的区别在于,List可以在任意位置添加和删除元素,
而队列只有两个操作:1.把元素添加到队列末尾;2.从队列头部取出元素。

数组队列

和普通数组的区别在于,array可以在任意位置添加和删除元素,
而队列只有两个操作:1.把元素添加到队列末尾;2.从队列头部取出元素。

思路

  1. 初始化:front,rear,max size
  2. isFull: rear == maxSize -1,isEmpty: rear == front
  3. addQueue:rear 后移,getQueue:front后移
  4. viewQueue,headQueue: 查看头部

缺点

该数组只能用一次,取出数据后空间不可用。可以改进成环形数组。

造轮子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class ArrayQueue {
private int maxSize;//数组最大容量
private int front;//队列头部
private int rear;//队列尾部
private int[] arr;//存放数据模拟队列

//初始化
public ArrayQueue(int maxSize){
this.maxSize = maxSize;
arr = new int[maxSize];
front = -1;//队列头部前一个位置
rear = -1;//队列尾部
}

//判断队列是否满
public boolean isFull(){
return rear == maxSize - 1;
}

//判断队列是否为空
public boolean isEmpty(){
return rear == front;
}

//添加值
public void addQueue(int n){
if(isFull()){
System.out.println("no available space in queue ");
return;
}
rear++;
arr[rear] = n;
}

//取值
public int getQueue(){
if(isEmpty()){
throw new RuntimeException("queue empty");
}
front++;
return arr[front];
}

//显示队列
public void viewQueue(){
if(isEmpty()){
System.out.println("empty queue");
return;
}
for(int x : arr){
System.out.println(x);
}
}

//查看头部
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("empty queue");
}
return arr[front + 1];
}
}

环形数组队列

实际上并没有实际的环形,对代码进行处理便可以实现虚拟环形。

思路

  1. front 指向队列第一个元素,初始值为0。
  2. rear 指向队列最后一个元素的后一个位置,预留一个位置作判断,初始值为0。
  3. (rear + 1)%maxSize == front ,队列为满.利用remainder查看虚拟环形下一个位置。

remainder 实际作用是让指针在规定区间移动,达到虚拟环绕效果
4. rear = front ,队列为空
5. 有效数据个数,(rear-front+maxSize)%maxSize

造轮子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public class CircleArrayQueue {
private int maxSize;//数组最大容量
private int front;//队列头部
private int rear;//队列尾部
private int[] arr;//存放数据模拟队列

//初始化
public CircleArrayQueue(int maxSize){
this.maxSize = maxSize;
arr = new int[maxSize];
}

//判断队列是否满
public boolean isFull(){
return (rear + 1)%maxSize == front;
}

//判断队列是否为空
public boolean isEmpty(){
return rear == front;
}

//添加值
public void addQueue(int n){
if(isFull()){
System.out.println("no available space in queue ");
return;
}
arr[rear] = n;
//remainder,超出范围往前跳
rear = (rear + 1) % maxSize;
}

//取值
public int getQueue(){
if(isEmpty()){
throw new RuntimeException("queue empty");
}
int temp = arr[front];
front = (front + 1)%maxSize;
return temp;
}

//显示队列
public void viewQueue(){
if(isEmpty()){
System.out.println("empty queue");
return;
}
for(int i = front;i<front+size();i++){
System.out.println("arr["+i%maxSize+"]= "+arr[i%maxSize] );
}
}

public int size(){
return (rear - front +maxSize)%maxSize;
}

//查看头部
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("empty queue");
}
return arr[front];
}

链表队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// A linked list (LL) node to store a queue entry 
class QNode {
int key;
QNode next;

// constructor to create a new linked list node
public QNode(int key)
{
this.key = key;
this.next = null;
}
}

// A class to represent a queue
// The queue, front stores the front node of LL and rear stores the
// last node of LL
class Queue {
QNode front, rear;

public Queue()
{
this.front = this.rear = null;
}

// Method to add an key to the queue.
void enqueue(int key)
{

// Create a new LL node
QNode temp = new QNode(key);

// If queue is empty, then new node is front and rear both
if (this.rear == null) {
this.front = this.rear = temp;
return;
}

// Add the new node at the end of queue and change rear
this.rear.next = temp;
this.rear = temp;
}

// Method to remove an key from queue.
void dequeue()
{
// If queue is empty, return NULL.
if (this.front == null)
return;

// Store previous front and move front one node ahead
QNode temp = this.front;
this.front = this.front.next;

// If front becomes NULL, then change rear also as NULL
if (this.front == null)
this.rear = null;
}
}
作者

黄港欢

发布于

2020-02-27

更新于

2021-03-13

许可协议