队列

抽象数据类型描述:

 

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 ]
posted @ 2012-03-02 23:45  七天的空白  阅读(207)  评论(0编辑  收藏  举报