介绍
队列的的操作也是数组的子集,不同的是,队列只能从一端(队尾)添加元素,只能从另一端(队首)取出元素。
队列实现
将队列定义为一个接口:
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
| public interface Queue<E> {
void enqueue(E e);
E dequeue();
E getFront();
int getSize();
boolean isEmpty(); }
|
使用动态数组实现队列:
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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
public class ArrayQueue<E> implements Queue<E> {
private Array<E> array;
public ArrayQueue(int capacity) { array = new Array<>(capacity); }
public ArrayQueue() { array = new Array<>(); }
@Override public int getSize() { return array.getSize(); }
@Override public boolean isEmpty() { return array.isEmpty(); }
public int getCapacity() { return array.getCapacity(); }
@Override public void enqueue(E e) { array.addLast(e); }
@Override public E dequeue() { return array.removeFirst(); }
@Override public E getFront() { return array.getFirst(); }
@Override public String toString() {
StringBuilder res = new StringBuilder(); res.append("Queue: "); res.append("front [");
for (int i = 0; i < array.getSize(); i++) { res.append(array.get(i)); if (i != array.getSize() - 1) { res.append(", "); } }
res.append("] tail");
return res.toString(); } }
|
使用循环队列解决数组队列出队复杂度高的问题:
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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
public class LoopQueue<E> implements Queue<E> { private E[] data; private int front, tail; private int size;
@SuppressWarnings("unchecked") public LoopQueue(int capacity) {
data = (E[]) new Object[capacity + 1]; front = 0; tail = 0; size = 0; }
public LoopQueue() { this(10); }
public int getCapacity() { return data.length - 1; }
@Override public boolean isEmpty() { return front == tail; }
@Override public int getSize() { return size; }
@Override public void enqueue(E e) {
if ((tail + 1) % data.length == front) { resize(getCapacity() * 2); }
data[tail] = e; tail = (tail + 1) % data.length; size++; }
@Override public E dequeue() { if (isEmpty()) { throw new IllegalArgumentException("Cannot dequeue from an empty queue."); } E ret = data[front]; data[front] = null; front = (front + 1) % data.length; size--;
if (size == getCapacity() / 4 && getCapacity() / 2 != 0) { resize(getCapacity() / 2); }
return ret; }
@Override public E getFront() { if (isEmpty()) { throw new IllegalArgumentException("Queue is empty."); } return data[front]; }
@SuppressWarnings("unchecked") private void resize(int newCapacity) { E[] newData = (E[]) new Object[newCapacity + 1];
for (int i = 0; i < size; i++) { newData[i] = data[(i + front) % data.length]; }
data = newData; front = 0; tail = size; }
@Override public String toString() { StringBuilder res = new StringBuilder(); res.append(String.format("QUeue: size = %d, capacity = %d\n", size, getCapacity())); res.append("front [");
for (int i = front; i != tail; i = (i + 1) % data.length) { res.append(data[i]); if ((i + 1) % data.length != tail) { res.append(", "); } } res.append("] tail"); return res.toString(); } }
|
使用链表实现队列:
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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
public class LinkedListQueue<E> implements Queue<E> {
private class Node { public E e; public Node next;
public Node(E e, Node next) { this.e = e; this.next = next; }
public Node(E e) { this(e, null); }
@Override public String toString() { return e.toString(); } }
private Node head, tail; private int size;
public LinkedListQueue() { head = null; tail = null; size = 0; }
@Override public int getSize() { return size; }
@Override public boolean isEmpty() { return size == 0; }
@Override public void enqueue(E e) { if (tail == null) { tail = new Node(e); head = tail; } else { tail.next = new Node(e); tail = tail.next; } size++; }
@Override public E dequeue() { if (isEmpty()) { throw new IllegalArgumentException("Cannot dequeue from an empty queue."); }
Node retNode = head; head = head.next; retNode.next = null; if (head == null) { tail = null; } size--; return retNode.e; }
@Override public E getFront() { if (isEmpty()) { throw new IllegalArgumentException("Queue is empty."); }
return head.e; }
@Override public String toString() {
StringBuilder res = new StringBuilder(); res.append("Queue: front ");
Node cur = head; while (cur != null) { res.append(cur + "->"); cur = cur.next; }
res.append("NULL tail");
return res.toString(); } }
|