队列
抽象数据类型描述:
public interface Queue { // 先进先出只能从队首删除、队尾插入 public void clear(); public void enqueue(Object obj); // 在队尾插入一个新元素 public Object dequeue(); // 删除并返回队首元素 public boolean isEmpty(); public int size(); public Object peek(); // 返回队首元素 }
数组实现队列:
public class ArrayQueue implements Queue { private static final int DEFAULT_SIZE = 10; private Object[] array; private int front; // 指向队首元素 private int rear; // 指向队尾元素的后继位置 private int count; // 构造方法,构造队列、初始化 public ArrayQueue() { array = new Object[DEFAULT_SIZE]; front = rear = count = 0; } public void clear() { for (int i = 0; i < array.length; i++) { array[i] = null; front = rear = count = 0; } } public Object dequeue() { if (count == 0) { throw new IllegalStateException(); } Object obj = array[front]; array[front++] = null; // 队首指针递增 if (front == array.length) { front = 0; } count--; return obj; } /* * 因为front=0时队列不一定为空,rear = array.length时队列不一定放满了。例如当rear = * array.length时,front=3,(array[0]、、array[1]、array[2]这3个元素已经删除 * front才会移动到3) * * * */ public void enqueue(Object obj) { if (count == array.length) { expand(); } array[rear++] = obj; // 队尾指针递增 if (rear == array.length) { rear = 0; } count++; } /* * 不论经过多少次的增加、删除,front与rear的具体位置在 哪里,最后当循环数组(队列) * 放满的时候:front = rear ,front + i其实就是将循环队列“拉直”,然后我们再给 * front赋值0,rear赋值array.length。当我们把数组元素复制到新数组之后队首位置就 * 在 新数组的左端啦。 * */ private void expand() { Object[] newArray = new Object[2 * array.length]; for (int i = 0; i < count; i++) { newArray[i] = array[(front + i) % array.length]; } front = 0; rear = array.length; array = newArray; } public boolean isEmpty() { return count == 0; } public Object peek() { if (count ==0) { throw new IllegalStateException(); } return array[front]; } public int size() { return count; } // 总是从头开始 public String toString() { String buf = new String("[ "); for (int i = 0; i < count; i++) { if (i > 0) { buf += ", "; } buf += array[(front + i) % array.length].toString(); } buf += " ]"; return buf; } }
单向链表实现队列:
public class LinkedQueue implements Queue { // 链表节点类 private static class SLLNode { private Object data; private SLLNode next; public SLLNode() { } public SLLNode(Object data) { this.data = data; } public SLLNode(Object data, SLLNode next) { this.data = data; this.next = next; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public SLLNode getNext() { return next; } public void setNext(SLLNode next) { this.next = next; } public String toString() { return data.toString(); } } private SLLNode front; // 指向单向链表第一个节点的引用 private SLLNode rear; // 指向单向链表最后一个节点的引用 private int count; public LinkedQueue () { clear(); } public void clear() { front = rear = null; count = 0; } public Object dequeue() { if (count == 0) { throw new IllegalStateException(); } Object obj = front.data; front = front.next; // 当前front没有了后继元素(即队列只剩下一个元素),删除后链表为空,队列为空 if (front == null) { rear = null; } count --; return obj; } public void enqueue(Object obj) { SLLNode temp = new SLLNode(obj, null); if (this.isEmpty()) { //队列为空 front = temp; } else { rear.next = temp; } rear = temp; count ++; } public boolean isEmpty() { return count == 0; // return rear == null; } public Object peek() { if (this.isEmpty()) { throw new IllegalStateException(); } return front.data; } public int size() { return count; } public String toString() { String buf = new String("[ "); for (SLLNode curr = front; curr != null; curr = curr.next) { if (curr != front) { buf += ", "; } buf += curr.data.toString(); } buf += " ]"; return buf; } }
测试类:
public class QueueTest { /** * @param args */ public static void main(String[] args) { Queue qa = new ArrayQueue(); int[] array = new int[]{1,2,3,4,5,6,7,8,9}; qa.enqueue("a"); qa.enqueue(1); qa.enqueue(array); qa.enqueue(array[3]); qa.enqueue(array.length); qa.enqueue("6"); System.out.println(qa.toString()); qa.dequeue(); // qa.dequeue(); System.out.println(qa.toString()); System.out.println(qa.size()); Queue ql = new LinkedQueue(); ql.enqueue(array); ql.enqueue(array.length); ql.enqueue(array.hashCode()); System.out.println(ql.toString()); } }
结果:
[ a, 1, [I@1fb8ee3, 4, 9, 6 ] [ 1, [I@1fb8ee3, 4, 9, 6 ] 5 [ [I@1fb8ee3, 9, 33263331 ]