使用数组实现顺序队列
1/**
2 * 使用数组实现一个固定容量的顺序队列。
3 *
4 * @author wangy
5 * @version 1.0
6 * @date 2021/6/28 / 15:09
7 */
8public class ArrayQueue {
9
10 private final int[] data;
11 // cap of data array
12 private final int cap;
13 // index of head element
14 private int head;
15 /*
16 关于tail指针,一般是将tail指向最新的可以插入元素的index,
17 即tail是一个空槽(slot):
18 ===================================================
19 data[0] data[7]
20 | | | 5 | 6 | 9 | 16 | | |
21 head tail
22 ===================================================
23 初始化时,head = tail = 0,此后每插入一个元素,tail后移一位。
24
25 当tail = cap且head=0,即认为队列"已满":
26 ===================================================
27 data[0] data[7]
28 | 14 | 8 | 5 | 6 | 9 | 16 | 87 | 67 |
29 head tail
30 ===================================================
31
32 当head = tail时,元素都已出队,此时队列为空:
33 ===================================================
34 data[0] data[7]
35 | | | | | | | | |
36 head
37 tail
38 ===================================================
39
40 特殊地,当tail = cap且head != 0时,数组明明有空间,元素却无法入队,
41 这时候就需要将head-tail指针重新整理了:
42 =======================================================
43 data[0] data[7]
44 | | | | | | 18 | 34 | 45 |
45 head tail
46 ======================================================================
47 | | data[0] data[7]
48 \ \---\¯\ | 18 | 34 | 45 | | | | | |
49 \ \--/_/ head tail
50 ======================================================
51 */
52 // index of tail
53 private int tail;
54
55 public ArrayQueue(int cap) {
56 this.data = new int[cap];
57 this.cap = cap;
58 head = tail = 0;
59 }
60
61
62 int getHead() {
63 if (isEmpty()) return -1;
64 return data[head];
65 }
66
67 int getTail() {
68 if (isEmpty()) return -1;
69 return data[tail - 1];
70 }
71
72 boolean isFull() {
73 return tail == cap && head == 0;
74 }
75
76 boolean isEmpty() {
77 return head == tail;
78 }
79
80 boolean reposition() {
81 return tail == cap && head != 0;
82 }
83
84 // 入队
85 int enQueue(int e) {
86 // full
87 if (isFull()) throw new ArrayStoreException("队列满了");
88 // 整理元素
89 if (reposition()) {
90 for (int i = head; i < tail; i++) {
91 data[i - head] = data[i];
92 data[i] = 0;
93 }
94 tail -= head;
95 head = 0;
96 }
97 data[tail++] = e;
98 return e;
99 }
100
101 // 出队
102 int deQueue() {
103 // empty
104 if (isEmpty()) throw new ArrayStoreException("队列为空");
105 return data[head++];
106 }
107
108
109 // 打印数组/队列
110 void printAll() {
111 System.out.println("数组:" + Arrays.toString(data));
112 System.out.print("队列:[");
113 if (!isEmpty()) {
114 //
115 for (int i = head; i < tail; i++) {
116 if (i == tail - 1)
117 System.out.print(data[i]);
118 else
119 System.out.print(data[i] + ", ");
120 }
121 }
122 System.out.println("]");
123 }
124
125 public static void main(String[] args) {
126 ArrayQueue aq = new ArrayQueue(3);
127 aq.enQueue(1);
128 System.out.println(aq.deQueue());
129 aq.enQueue(2);
130 aq.enQueue(3);
131 aq.enQueue(4);
132
133 System.out.println(aq.deQueue());
134 System.out.println(aq.deQueue());
135 // System.out.println(aq.deQueue());
136
137 System.out.printf("队列头尾索引和值:%s: %s, %s: %s%n",
138 aq.head,
139 aq.getHead(),
140 aq.tail,
141 aq.getTail());
142 aq.printAll();
143 }
144}