栈是一种线性的数据结构 特性:尾部添加,头部取出 即先进先出FIFO 操作:enqueue入队 dequeue出队 getFront查看队首元素
队列.png基于数组实现的队列在队首取出是会使得整队移动,而使时间复杂度为O(n) 可以使用循环队,基于队首队尾两个标示来固定队列,从而使得时间复杂度为O(1) 循环队列特点:为空时,队尾标示==队首标示,新加元素时,队尾表识后移, 队列满:(队尾标示+1)%数组长度==队首标示 循环队列会使队首前一个位置不可用。
循环队列.png 循环队列循环机制.png /** * 作者:张风捷特烈 * 时间:2018/8/17 0017:16:03 * 邮箱:1981462002@qq.com * 说明:数组实现循环队列 */ public class ArrayLoopQueue<T> implements IQueue<T> { /** * 队列数据 */ private T[] data; /** * 队首标示 */ private int front; /** * 队尾标示 */ private int tail; /** * 元素个数 */ private int size; /** * 无参构造:默认10个容量 */ public ArrayLoopQueue() { this(11); } /** * 一参构造 * * @param capacity 队列容量 */ public ArrayLoopQueue(int capacity) { // 因为会有一个浪费,所以+1 data = (T[]) new Object[capacity + 1]; front = 0; tail = 0; size = 0; } @Override public void enqueue(T el) { if (isFull()) { grow(getCapacity() * 2); } data[tail] = el; //插入数据时对尾标示进行操作 tail = (tail + 1) % data.length; size++; } @Override public T dequeue() { if (isEmpty()) { throw new IllegalArgumentException("Cannot dequeue from an empty queue"); } T ret = data[front]; data[front] = null; //插入数据时对首标示进行操作 front = (front + 1) % data.length; size--; if (size == getCapacity() / 4 && getCapacity() / 2 != 0) { grow(getCapacity() / 2); } return ret; } @Override public T getFront() { if (isEmpty()) { throw new IllegalArgumentException("Cannot dequeue from an empty queue"); } return data[front]; } /** * 重新确定容量 * @param newCapacity 新的容量 */ private void grow(int newCapacity) { T[] newData = (T[]) new Object[newCapacity + 1]; for (int i = 0; i < size; i++) { // 此时在newData中队首对齐回来,data中就得有一个front的偏移量 newData[i] = data[(i + front) % data.length]; } data = newData; front = 0; tail = size; } /** * 获取容量 * @return 容量 */ public int getCapacity() { return data.length - 1; } /** * 队列元素个数 * @return 元素个数 */ @Override public int getSize() { return size; } /** * 是否为空 * @return 是否为空 */ @Override public boolean isEmpty() { return front == tail; } /** * 队列是否满了 * @return 队列是否满了 */ public boolean isFull() { // tail的下一个位置等于front时 return (tail + 1) % data.length == front; } @Override public String toString() { StringBuilder res = new StringBuilder(); res.append(String.format("ArrayLoopQueue: size = %d, capacity = %d\n", size, getCapacity())); res.append("front ["); for (int i = front; i != tail; i = (i + 1) % data.length) { res.append(data[i]); if ((i + 1) % data.length != tail) // 最后一个元素不要加, res.append(", "); } res.append("] tail"); return res.toString(); } }链表和队列可谓天然配,链表的头删除,头获取都是O(1),但尾添加是O(n),但可以维护首位标识,使尾加也为O(1)
/** * 作者:张风捷特烈 * 时间:2018/8/17 0017:22:50 * 邮箱:1981462002@qq.com * 说明:单链表实现队列 */ public class SingleLinkedQueue<T> implements IQueue<T> { /** * 头节点 */ private Node head; /** * 尾节点 */ private Node tail; /** * 元素个数 */ private int size; public SingleLinkedQueue() { head = null; tail = null; size = 0; } @Override public void enqueue(T el) { // 如果队尾为空,说明队列是空的。因为tail一直指向最后一个非空节点。 if (tail == null) { tail = new Node(null, el); head = tail; } else { // 使用tail.next把新Node挂载上来。 tail.next = new Node(null, el); // tail后挪 tail = tail.next; } size++; } @Override public T dequeue() { if (isEmpty()) throw new IllegalArgumentException("Cannot dequeue from an empty queue."); Node targetNode = head; head = head.next; // head后移 targetNode.next = null; // 元素置空 if (head == null) {// 如果头结点为空 tail = null; } size--; return targetNode.el; } @Override public T getFront() { if (isEmpty()) throw new IllegalArgumentException("IQueue is empty."); return head.el; } @Override public int getSize() { return size; } @Override public boolean isEmpty() { return size == 0; } @Override public String toString() { StringBuilder res = new StringBuilder(); res.append("IQueue: front "); Node cur = head; while (cur != null) { res.append(cur + "->"); cur = cur.next; } res.append("NULL tail"); return res.toString(); } private class Node { public T el;//改节点上的元素 public Node next; //下一节点 /** * 两参构造 * * @param next //下一节点 * @param el 生成节点的元素值 */ public Node(Node next, T el) { this.el = el; this.next = next; } @Override public String toString() { return el.toString(); } } }[1]本文由张风捷特烈原创,各图均由本人亲自所画,转载请注明 [2]欢迎广大编程爱好者共同交流 [3]个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正 [4]你的喜欢与支持将是我最大的动力
更多数据结构知识欢迎访问:图解数据结构 项目源码均在我的https://github.com/toly1994328/DS:欢迎star 张风捷特烈个人网站,编程笔记请访问:http://www.toly1994.com
QQ:1981462002 邮箱:1981462002@qq.com 微信:zdl1994328
转载于:https://www.cnblogs.com/toly-top/p/9781866.html
相关资源:图解数据结构(使用Python)——队列