队列 Queue
您目前处于:编程  2013年06月21日

1. 队列Queue

定义:

队列又叫做FIFO(先进先出)表,即first-in,first-out

现实中的队列

——排队

队列的接口

public interface QueueInterface<T> {
    /**
     * 将新元素插入队列后端
     * @param newEntry 待插入的对象 */
    public void enqueue(T newEntry);
    /**
     * 删除并返回队列前端对象
     * @return 位于队列前端的对象,如果队列为空则返回null */
    public T dequeue();
    /**
     * 检索队列前端对象
     * @return 位于队列前端的对象,如果队列为空则返回null */
    public T getFront();
    /**
     * 检查队列是否为空
     * @return 如果队列为空则返回true */
    public boolean isEmpty();
    /**
     * 从队列中删除所有元素 */
    public void clear();
}

Java类库:Queue接口

public interface Queue<T> {
    // 在对象的末端插入一个新元素,如果插入成功则返回true,否则抛出一个异常
    public boolean add(T newEntry);
    // 在对象的末端插入一个新元素,根据此操作成功与否返回true或false
    public boolean offer(T newEntry);
    // 在队列的前端检索并删除元素,如果在此操作之前队列已为空,则抛出异常NoSuchElementException
    public T remove();
    // 在队列的前对检索并删除元素,如果在此操作之前队列已为空,则返回null
    public T poll();
    // 检索队列前端的元素,如果队列为空,则抛出异常NoSuchelementException
    public T element();
    // 检索队列前端的元素,如果队列为空,则返回null
    public T peek();
    // 检索队列是否为空
    public boolean isEmpty();
    // 删除队列的所有元素
    public void clear();
    // 获得当前队列中的元素数据
    public int size();
    // 返回作用于队列的元素的迭代期器
    public Iterator<T> iterator();
}

双端队列接口描述

public interface DequeInterface<T> {
                                
    public void addToFront(T newEntry);
    public void addToBack(T newEntry);
    public T removeFront();
    public T removeBack();
    public T getFront();
    public T getBack();
    public boolean isEmpty();
    public void clear();   
}

优先队列的接口描述

public interface PriorityQueueInterface<T extends Comparable<? super T>> {
    /**
     * 将新元素插入优先队列
     * @param newEntry newEntry一个对象 */
    public void add(T newEntry);
    /**
     * 删除并返回优先队列最高的元素
     * @return 优先级最高的对象,如果优先队列为空则返回null */
    public T remove();
    /**
     * 检索优先级最高的元素
     * @return 优先级最高的对象,如果优先队列为空则返回null */
    public T peek();
    /**
     * 检索优先队列是否为空
     * @return 如果优先队列为空则返回true */
    public boolean isEmpty();
    /**
     * 缺德优先队列的长度
     * @return 当前优先队列中的元素数据 */
    public int getSize();
    /**
     * 从优先队列中删除所有元素 */
    public void clear();
}

2. 基于(双端)链表的队列实现

public class LinkedQueue<T> implements QueueInterface<T>, Serializable {
    private Node firstNode; // 引用队列前端的结点
    private Node lastNode; // 引用队列后端的结点
    public LinkedQueue() {
        firstNode = null;
        lastNode = null;
    }
    private class Node implements Serializable {
        private T data; // entry in queue
        private Node next; // link to next queue
    }
    // 在后端插入
    public void enqueue(T newEntry) {
        Node newNode = new Node(newEntry, null);
        if (isEmpty())
            firstNode = newNode;
        else
            lastNode.setNext(newNode);
        lastNode = newNode;
    }
    // 删除前端元素
    public T dequeue() {
        T front = null;
        if (!isEmpty()) {
            front = firstNode.getData();
            firstNode = firstNode.getNext();
            if (firstNode == null)
                lastNode = null;
        }
        return front;
    }
    // 检索前端元素
    public T getFront() {
        T front = null;
        if (!isEmpty())
            front = firstNode.getData();
        return front;
    }
    public boolean isEmpty() {
        return firstNode == null;
    }
    public void clear() {
        firstNode = null;
        lastNode = null;
    }
}

3. 基于(循环)数组的队列实现

public class ArrayQueue<T> implements QueueInterface<T>, Serializable {
    private T[] queue; // 存放队列元素的循环数组
    private int frontIndex;
    private int backIndex;
    private static final int DEFAULT_INITIAL_CAPACITY = 50;
    public ArrayQueue() {
        this(DEFAULT_INITIAL_CAPACITY);
    }
    public ArrayQueue(int initialCapacity) {
        queue = (T[]) new Object[DEFAULT_INITIAL_CAPACITY   1];
        frontIndex = 0;
        backIndex = initialCapacity;
    }
    // 在后端插入
    public void enqueue(T newEntry) {
        if (isArrayFull()) {
            // 扩建数组
        }
        backIndex = (backIndex   1) % queue.length; // 由于数组是循环的,需要使用取余 % 操作符,以使backIndex达到其最大值之后变回0
        queue[backIndex] = newEntry;
    }
    // 删除前端元素
    public T dequeue() {
        T front = null;
        if (!isEmpty()) {
            front = queue[frontIndex];
            queue[frontIndex] = null;
            frontIndex = (frontIndex   1) % queue.length;
        }
        return front;
    }
    // 检索前端元素
    public T getFront() {
        T front = null;
        if (!isEmpty())
            front = queue[frontIndex];
        return front;
    }
    public boolean isEmpty() {
        return frontIndex == ((backIndex   1)  %  queue.length);
    }
    private boolean isArrayFull() {
        return frontIndex == ((backIndex   2)  %  queue.length);
    }
}

4. 基于双端链表的双端队列实现

public class LinkedDeque<T> implements DequeInterface<T>, Serializable {
    private DLNode firstNode; // 引用双端队列的前端结点
    private DLNode lastNode; // 引用双端队列的后端结点
    public LinkedDeque() {
        firstNode = null;
        lastNode = null;
    }
    private class DLNode implements Serializable {
        private T data;
        private DLNode next;
        private DLNode previous;
    }
    // 插入元素
    public void addToBack(T newEntry) {
        DLNode newNode = new DLNode(newEntry, lastNode, null);
        if(isEmpty())
            firstNode = newNode;
        else
            lastNode.setNext(newNode);
        lastNode = newNode;
    }
    public void addToFront(T newEntry) {
        DLNode newNode = new DLNode(newEntry, null, firstNode);
        if(isEmpty())
            lastNode = newNode;
        else
            firstNode.setPrevious(newNode);
        firstNode = newNode;
    }
    // 删除元素
    public T removeFront() {
        T front = null;
        if(!isEmpty()) {
            front = firstNode.getData();
            firstNode = firstNode.getNext();
            if(firstNode == null)
                lastNode = null;
            else firstNode.setPrevious(null);
        }
        return front;
    }
    public T removeBack() {
        T back = null;
        if(!isEmpty()) {
            back = lastNode.getData();
            lastNode = lastNode.getPrevious();
            if(lastNode == null)
                firstNode = null;
            else
                lastNode.setNext(null);
        }
        return back;
    }
}

5. 实现优先队列的方法

可以使用数组或链表实现优先队列。

但使用堆实现优先队列是一种更高效的方法。


转载请并标注: “本文转载自 linkedkeeper.com ”