抽象数据类型描述:
package org.zp.datastruct;
public interface Queue {
// 先进先出只能从队首删除、队尾插入
public void clear();
public void enqueue(Object obj); // 在队尾插入一个新元素
public Object dequeue(); // 删除并返回队首元素
public boolean isEmpty();
public int size();
public Object peek(); // 返回队首元素
}
数组实现队列:
package org.zp.datastruct;
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;
}
}
单向链表实现队列:
package org.zp.datastruct;
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;
}
}
测试类:
package org.zp.datastruct;
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 ]