队列小实现
程序员文章站
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)从空间上看,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的问题。而链式队列不存在这个问题,尽管它需要一个指针域,会产生一些空间上的开销,但也可以接受。所以在空间上,链式队列更加灵活。
上一篇: Python去除字符串中的空字符
下一篇: POJ1915,双向宽度优先搜索