欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

队列小实现

程序员文章站 2022-05-24 09:38:42
...
package cn.smallbug.datastructure.queue;

/**
 * 队列接口
 * 
 * @timestamp Feb 23, 2016 3:28:20 PM
 * @author smallbug
 * @param <T>
 */
public interface Queue<T> {

	/**
	 * 入队列
	 * 
	 * @timestamp Feb 23, 2016 3:28:31 PM
	 * @param obj
	 * @return
	 */
	public boolean enQueue(T obj);

	/**
	 * 出队列
	 * 
	 * @timestamp Feb 23, 2016 3:28:51 PM
	 * @return
	 */
	public T deQueue();

	/**
	 * 队列是否为空
	 * 
	 * @timestamp Feb 23, 2016 3:28:59 PM
	 * @return
	 */
	public boolean isEmpty();

	/**
	 * 队列中元素个数
	 * 
	 * @timestamp Feb 23, 2016 3:29:36 PM
	 * @return
	 */
	public int size();

	/**
	 * 获取对头元素(不删除)
	 * 
	 * @timestamp Feb 23, 2016 3:30:03 PM
	 * @return
	 */
	public T getFirst();
}

 

package cn.smallbug.datastructure.queue;

/**
 * 队列异常
 * 
 * @timestamp Feb 23, 2016 3:50:19 PM
 * @author smallbug
 */
public class QueueException extends RuntimeException {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3156992864706426492L;

	public QueueException() {

		this(null, null);

	}

	public QueueException(String message) {

		this(message, null);

	}

	public QueueException(Throwable throwable) {

		this(null, throwable);

	}

	public QueueException(String message, Throwable throwable) {

		super();
		this.message = message;
		this.throwable = throwable;

	}

	protected String message = null;

	protected Throwable throwable = null;

	public String getMessage() {

		return (message);

	}

	public Throwable getThrowable() {

		return (throwable);

	}

	public String toString() {

		StringBuilder sb = new StringBuilder("QueryException:  ");
		if (message != null) {
			sb.append(message);
			if (throwable != null) {
				sb.append(":  ");
			}
		}
		if (throwable != null) {
			sb.append(throwable.toString());
		}
		return (sb.toString());

	}

}

 

package cn.smallbug.datastructure.queue;

/**
 * 数组结构实现的队列
 * 
 * @timestamp Feb 23, 2016 3:32:44 PM
 * @author smallbug
 */
public class ArrayQueue<T> implements Queue<T> {

	private int defaultSize = 10; // 默认队列的长度
	private int front; // 队头
	private int rear; // 队尾
	private int count; // 统计元素个数的计数器
	private int maxSize; // 队的最大长度
	private T[] queue; // 队列

	/**
	 * 默认大小
	 */
	public ArrayQueue() {
		init(defaultSize);
	}

	/**
	 * 指定大小
	 * 
	 * @param maxSize
	 */
	public ArrayQueue(int maxSize) {
		if (maxSize <= 0)
			throw new IllegalArgumentException("maxSize mast greater than 0!");
		init(maxSize);
	}

	/**
	 * 初始化
	 * 
	 * @timestamp Feb 23, 2016 3:42:20 PM
	 * @param maxSize
	 */
	@SuppressWarnings("unchecked")
	private void init(int maxSize) {
		this.maxSize = maxSize;
		front = rear = 0;
		count = 0;
		queue = (T[]) new Object[maxSize];
	}

	@Override
	public boolean enQueue(T obj) {
		if (obj == null) {
			throw new QueueException("object not null!");
		}
		if (count > 0 && rear == front) {
			return false;
		}
		queue[rear] = obj;
		count++;
		rear = (rear + 1) % maxSize;
		return true;
	}

	@Override
	public T deQueue() {
		if (count == 0 && rear == front) {
			return null;
		}
		T obj = queue[front];
		queue[front] = null;
		count--;
		front = (front + 1) % maxSize;
		return obj;
	}

	@Override
	public boolean isEmpty() {
		return count == 0 ? true : false;
	}

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

	@Override
	public T getFirst() {
		if (count > 0)
			return queue[front];
		return null;
	}

}

 

package cn.smallbug.datastructure.queue;

/**
 * 链表结构实现的循环队列
 * 
 * @timestamp Feb 23, 2016 3:32:02 PM
 * @author smallbug
 */
public class LinkedQueue<T> implements Queue<T> {

	private Node<T> front; // 队头
	private Node<T> rear; // 队尾
	private int count; // 计数器

	private int maxSize = -1;// 最大元素个数

	public LinkedQueue() {
		init();
	}

	public LinkedQueue(int maxSize) {
		if (maxSize <= 0) {
			throw new IllegalArgumentException("maxSize mast greater than 0!");
		}
		init();
		this.maxSize = maxSize;
	}

	private void init() {
		front = rear = null;
		count = 0;
	}

	@Override
	public boolean enQueue(T obj) {
		if (obj == null) {
			throw new QueueException("object not null!");
		}
		if (maxSize != -1 && maxSize == count)
			return false;
		Node<T> node = new Node<T>(obj, null);
		if (rear != null) {
			rear.next = node;
		}
		rear = node;
		if (front == null) {
			front = node;
		}
		count++;
		return true;
	}

	@Override
	public T deQueue() {
		if (isEmpty())
			return null;
		T t = front.getElement();
		front = front.next;
		count--;
		return t;
	}

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

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

	@Override
	public T getFirst() {
		if (!isEmpty()) {
			return front.getElement();
		} else {
			return null;
		}
	}

	private class Node<D> {

		private D element; // 数据域
		private Node<D> next; // 指针域

		// 头结点的构造方法
		public Node(Node<D> nextval) {
			this.next = nextval;
		}

		// 非头结点的构造方法
		public Node(D obj, Node<D> nextval) {
			this(nextval);
			this.element = obj;
			this.next = nextval;
		}

		// 获得当前的数据域的值
		public D getElement() {
			return this.element;
		}
	}
}

 

循环队列和链式队列的比较:

     (1)从时间上看,它们的基本操作都是常数时间,即O(1)的。不过循环队列是事先申请好空间,使用期间不释放;而链式队列,每次申请和释放结点也会存在一定的时间开销,如果入栈和出栈比较频繁,则两者还是有细微的差别。

     (2)从空间上看,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的问题。而链式队列不存在这个问题,尽管它需要一个指针域,会产生一些空间上的开销,但也可以接受。所以在空间上,链式队列更加灵活。