定义
队列(queue)是一种特殊的线性表,它只允许在表的前端进行删除,在表的后端进行插入。
进行插入端的称为队尾,进行删除端的称为队头。队列是先进先出原则的。队列的实现同样可以
使用两种方式来实现,一种是数的实现方式,另一种是链表的实现方式。
队列的实现
我们已经知道队列已经有两种方式实现,虽然底层的实现方式不同,但是其具有的方法是相同
的,我们采用接口定义其具有的操作。
package com.kiritor; /** * 队列FIFO的接口 * @author Kiritor * */ public interface Queue<T> { /** * 入队:从队尾加入一个元素 * @param t * */ void add(T t); /** * 出队:移走队头元素并返回 * @return 当前队头元素*/ T remove(); /** * 当前队列的元素个数*/ int size(); /** * 判断当前队列是否为空 * @return */ boolean isEmpty(); /** * 只是返回队头元素,并未删掉 * @return t*/ T front(); }
队列的数组实现
package com.kiritor; import java.util.Arrays; /** * 基于数组实现的队列 * @author Kiritor*/ public class ArrayQueue<T> implements Queue<T>{ private T[] data; private int size;//元素个数 private int front;//队列中第一个对象的位置 private int rear;//队列中当前对象的位置 public ArrayQueue() { data = (T[]) new Object[10]; size = 0; front =0; rear = 0; } @Override public void add(T t) { if(isFull()) { resize(); front = 0; } rear = (front+size)%data.length; System.out.println(rear); data[rear] = t; size++; } @Override public T remove() { if (isEmpty()) { throw new RuntimeException("队列为空!"); } T tempData = data[front]; data[front] = null; //思考一下这里有必要进行除法运算吗? front = (front + 1) % (data.length); size--; return tempData; } @Override public int size() { return size; } @Override public boolean isEmpty() { return size == 0; } @Override public T front() { if (isEmpty()) { throw new RuntimeException("队列为空!"); } return data[front]; } /** * 判断当前队列是否已满 * @return*/ public boolean isFull() { return size == data.length; } /** * 扩容,2倍 * */ public void resize() { /*注意重新扩容的时候并不需要去设置size * 队列的大小并不能通过数组的大小直观的显示出来。 * 但是栈就可以直观的通过数组的大小显示出来*/ T[] tmp = (T[]) new Object[data.length*2]; System.arraycopy(data, 0, tmp, 0, data.length); data = tmp; tmp = null;//引用置为空,便于gc处理 } public static void main(String[] args) { ArrayQueue<String> q = new ArrayQueue<String>(); q.add("a"); q.add("b"); q.add("c"); q.add("d"); q.add("e"); q.add("f"); q.add("g"); q.add("h"); q.add("i"); q.add("j"); q.add("k"); q.add("l"); q.add("m"); while( !q.isEmpty() ){ String temp = q.remove(); System.out.println(temp); } } }
队列的链表实现
package com.kiritor; /** * 队列的链表实现 * @author Kiritor * @param <T>*/ public class LinkQueue<T> implements Queue<T> { private Node head; private Node rear; private int size; public LinkQueue() { head = null; rear = null; size = 0; } class Node { T data; Node next; public Node() { //无参构造 } public Node(T t) { this.data = t; } } /** * 从队列的尾部插入结点*/ @Override public void add(T t) { Node node = new Node(t); /*如果是队列则头部和尾部都执行Node*/ if(isEmpty()) head = node; else rear.next = node; rear = node; size++;//队列长度+1 } /** * 从队列的头部删除 * @return T*/ @Override public T remove() { T tmp; if(isEmpty()){ new NullPointerException("队列是空的!"); tmp = null; } else { if(null==head.next ) rear = null; tmp = head.data; head = head.next; size--; } return tmp; } @Override public int size() { return size; } @Override public boolean isEmpty() { return head == null; } /** * 查看队列头部,不做任何处理*/ @Override public T front() { if(head !=null) return head.data; return null; } public static void main(String[] args) { LinkQueue<String> q = new LinkQueue<String>(); q.add("a"); q.add("b"); q.add("c"); q.add("d"); q.add("e"); q.add("f"); q.add("g"); q.add("h"); q.add("i"); q.add("j"); q.add("k"); q.add("l"); q.add("m"); System.out.println(q.size); while( !q.isEmpty() ){ String temp = q.remove(); System.out.println(temp); System.out.println(q.size()); } } }
看下链队列的演示操作吧
转载于:https://blog.51cto.com/kiritor/1226681