数据结构(Java)——队列的实现

兴亡谁人定,胜败岂无凭——易中天《百家讲坛》
不得慕虚名而处实祸 ——曹操

1. 概述

队列是一种线性集合,其元素从一端加入,从另一端删除。因此队列是按照先进先出方式处理的,从队列中删除元素的次序与往队列里放置元素的的次序是一样的。
由于队列是一种线性集合,因此可以像处理栈一样,把队列实现成一种LinearNode对象的链表。

2. 队列ADT

队列核心功能的声明:

package ds.java.ch05.queueImpl;
/** 
 * @author LbZhang
 * @version 创建时间:2015年11月16日 下午7:06:32 
 * @description 队列接口
 */
public interface QueueADT<T> {

    public void enqueue(T elem);
    public T dequeue();
    public T first();

    public boolean isEmpty();

    public int size();
    public String toString();


}

3. 链表实现队列

使用两个分别指向链表受元素、链表末元素的引用方便队列的链表实现。

package ds.java.ch05.queueImpl;
/**
 * 结点类的声明
 * @author MrLBZ
 * @param <T>
 */
public class LinearNode<T> {
    private LinearNode<T> next;
    private T element;


    public LinearNode() {
        next = null;
        element = null;
    }


    public LinearNode(T elem) {
        next = null;
        element = elem;
    }

    public LinearNode<T> getNext() {
        return next;
    }

    public void setNext(LinearNode<T> node) {
        next = node;
    }

    public T getElement() {
        return element;
    }

    public void setElement(T elem) {
        element = elem;
    }
}

package ds.java.ch05.queueImpl;



public class EmptyCollectionException extends RuntimeException
{
   /**
    * Sets up this exception with an appropriate message.
    */
   public EmptyCollectionException (String collection)
   {
      super ("The " + collection + " is empty.");
   }
}

package ds.java.ch05.queueImpl;

/**
 * @author LbZhang
 * @version 创建时间:2015年11月16日 下午7:30:59
 * @description 链表实现队列
 */
public class LinkedQueue<T> implements QueueADT<T> {

    private int count;
    private LinearNode<T> head, tail;

    // 首尾声明

    /**
     * 初始化队列
     */
    public LinkedQueue() {
        count = 0;
        head = tail = null;

    }

    @Override
    public void enqueue(T elem) {
        LinearNode<T> node = new LinearNode<T>(elem);
        if (isEmpty()) {// /如果是空的话初始化头结点
            head = node;
        } else {
            tail.setNext(node);
        }
        tail = node;// /新结点的next不需要显式的设置 因为在new一个新结点的时候已经设置完毕
        count++;
    }

    @Override
    public T dequeue() throws EmptyCollectionException{
        if (isEmpty()) {
            throw new EmptyCollectionException("queue");
        }
        T result = head.getElement();
        head = head.getNext();
        count--;
        if (isEmpty()) {
            tail = null;// /如果栈变成了空栈
        }
        return result;
    }

    @Override
    public T first() throws EmptyCollectionException{
        if (isEmpty())
            throw new EmptyCollectionException("queue");

        return head.getElement();
    }

    @Override
    public boolean isEmpty() {

        return (count == 0);
    }

    @Override
    public int size() {

        return count;
    }

    @Override
    public String toString() {
        String result = "";
        LinearNode<T> current = head;

        while (current != null) {
            result = result + (current.getElement()).toString() + "
";
            current = current.getNext();
        }

        return result;
    }
}

4. 数组实现队列

把数组看作是环形的,可以除去在队列的数组实现中把元素移位的需要。

package ds.java.ch05.queueImpl;

/**
 * @author LbZhang
 * @version 创建时间:2015年11月16日 下午10:14:12
 * @description 环形数组 可以除去在队列的数组实现中元素移位的需要
 */
public class CircularArrayQueue<T> implements QueueADT<T> {

    private final static int DEFAULT_CAPACITY = 100;
    private int front, rear, count;
    private T[] queue;// 数组队列

    public CircularArrayQueue() {
        this(DEFAULT_CAPACITY);

    }

    public CircularArrayQueue(int initc) {

        front = rear = count = 0;
        queue = (T[]) (new Object[initc]);
    }

    @Override
    public void enqueue(T elem) {
        if (size() == queue.length) {
            expandCapacity();
        }
        queue[rear] = elem;
        rear = (rear + 1) % queue.length;// 设置尾坐标
        count++;
    }

    private void expandCapacity() {
        // /开辟数组
        T[] larger = (T[]) (new Object[queue.length * 2]);

        // 复制数组
        for (int scan = 0; scan < count; scan++) {
            larger[scan] = queue[front];// 从front开始复制
            front = (front + 1) % queue.length;
        }

        // /重置首尾结点
        front = 0;
        rear = count;

        queue = larger;

    }

    /**
     * 出队列
     */
    @Override
    public T dequeue() {
        if (isEmpty())
            throw new EmptyCollectionException("queue");

        T result = queue[front];// 获取front的结点内容
        queue[front] = null;// 置空front结点
        front = (front + 1) % queue.length;// front后移
        count--;
        return result;
    }

    @Override
    public T first() {
        if (isEmpty())
            throw new EmptyCollectionException("queue");

        T result = queue[front];// 获取front的结点内容
        return result;
    }

    @Override
    public boolean isEmpty() {
        return (count == 0);
    }

    @Override
    public int size() {
        return count;
    }

    @Override
    public String toString() {
        String result = "";
        int scan = 0;

        while (scan < count) {
            if (queue[scan] != null) {
                result += queue[scan].toString() + "
";
            }
            scan++;
        }

        return result;
    }

}
踏实 踏踏实实~
原文地址:https://www.cnblogs.com/mrzhang123/p/5365838.html