生活中,排队随处可见。下面我们就使用java来实现简单的队列吧。
首先,给出接口的定义,也就是规定队列的行为...
package net.itaem.list; /** * 定义一个队列的接口 * * 队列的定义:FIRST IN FIRST OUT * * @author luohong QQ 846705189 * */ public interface Queue<T> { /** * 在队尾加入一个元素 * */ public void in(T e); /** * 从队列头部弹出一个元素,并且删除头部元素 * */ public T out(); /** * 返回队列元素长度 * */ public int size(); /** * 清空一个队列 * */ public void clear(); /** * 获得队列的第一个元素,不删除 * */ public T getFirst(); /** * 获得队列的最后一个元素,不删除 * */ public T getLast(); }
package net.itaem.list.impl; import net.itaem.list.Queue; /** * 使用数组来实现一个队列 * * 这个队列在初始化时就已经确定了队列可以容纳的数量,并且不会动态增长... * * @author luohong QQ 846705189 * * */ public class ArrayQueue<T> implements Queue<T>{ //队列首部 private int first; //队列尾部的下一个元素 private int last; //定义一个Object[]来保存队列的元素 private Object[] elements; //队列元素的size private int size; //队列最多能保存的元素个数 private int length; public ArrayQueue(){ //默认情况下,长度为10 this(10); } public ArrayQueue(int length){ if(length < 0) throw new RuntimeException("sorry,不能为负数"); this.length = length +1; elements = new Object[this.length]; } @Override public void in(T e) { if(last < length-1){ size++; elements[last++] = e; }else{ throw new RuntimeException("队列已满,不可以继续添加元素"); } } @SuppressWarnings("unchecked") @Override public T out() { T result = null; if(size > 0) { result = (T)elements[first]; //这里的first一直都等于0 for(int i=0; i<size; i++){ elements[i] = elements[i+1]; //移动后面的算有元素 } //尾部元素移动 last--; //元素长度减去一 size--; }else{ throw new RuntimeException("队列为空,不能继续弹出元素"); } return result; } @Override public int size() { return size; } @Override public void clear() { //清空数组的所有应用,防止造成内容溢出 for(int i=0; i<size; i++){ elements[i] = null; } last = 0; size = 0; } @SuppressWarnings("unchecked") @Override public T getFirst() { if(size > 0) return (T)elements[0]; else return null; } @SuppressWarnings("unchecked") @Override public T getLast() { if(size > 0) return (T)elements[last-1]; else return null; } public String toString(){ StringBuilder sb = new StringBuilder(); if(size == 0) sb.append("null"); else for(int i=0; i<size; i++){ sb.append(elements[i] + " "); } return "the queue size is " + size + " and the element is " + sb.toString(); } public static void main(String[] args) { Queue<Integer> intQueue = new ArrayQueue<Integer>(10); for(int i=0; i<10; i++){ intQueue.in(i); } System.out.println("before out " + intQueue); System.out.print("queue out "); for(int i=0; i<10; i++){ System.out.print(intQueue.out() + " "); } System.out.println(""); System.out.println("after out " + intQueue); //1000进入队列 intQueue.in(1000); System.out.println(intQueue.getFirst()); System.out.println(intQueue.getLast()); System.out.println("after 1000 in queue and " + intQueue); } }
before out the queue size is 10 and the element is 0 1 2 3 4 5 6 7 8 9 queue out 0 1 2 3 4 5 6 7 8 9 after out the queue size is 0 and the element is null 1000 1000 after 1000 in queue and the queue size is 1 and the element is 1000
上面使用数组实现的顺序队列,在使用上有着很大的闲置。因为会造成假溢出现象,并且长度是有限制的,不能动态的增长,而且在弹出元素时,算法效率低下...所以这种情况,可以使用循环队列。不过链式队列可以更加灵活的改善这些缺点,下面给出链式队列
package net.itaem.list.impl; import net.itaem.list.Queue; public class LinkedQueue<T> implements Queue<T> { private class Node<E>{ private E data; private Node<E> next; public Node(E data, Node<E> next){ this.data = data; this.next = next; } public E data(){ return data; } public void setData(E data){ this.data = data; } public Node<E> next(){ return next; } public void setNext(Node<E> next){ this.next = next; } } //定义头结点和尾节点 private Node<T> first; private Node<T> last; //保存队列元素个数 private int size; public LinkedQueue(){ //初始化一个空的节点 first = last = new Node<T>(null, null); } @Override public void in(T e) { Node<T> newElement = new Node<T>(e, null); //新建一个节点 last.setNext(newElement); //将节点添加到链表中 last = newElement; //修改尾节点指向新的节点 size++; //动态增长 } @Override public T out() { //找到第一个节点 Node<T> p = null; T result = null; if(first.next() != null){ p = first.next(); result = p.data(); first.setNext(first.next().next()); //修改头元素 size--; }else{ throw new RuntimeException("队列为空,不能进行出队列操作"); } if(p == last){ last = first; //该队列为空,需要将尾节点指向头结点 } //释放节点 p = null; return result; } @Override public int size() { return size; } @Override public void clear() { Node<T> p = first; while((p = p.next()) != null){ p.setData(null); //释放应用 p.setNext(null); } size = 0; last = first; //将尾节点指向头结点,代表队列为空 } @Override public T getFirst() { T result = null; if(first.next() != null){ result = first.next().data(); } return result; } @Override public T getLast() { if(last.data() != null){ return last.data(); }else{ return null; } } public String toString(){ Node<T> p = first; StringBuilder sb = new StringBuilder(); if(p.next() == null) sb.append("null"); else while((p = p.next()) != null){ sb.append(p.data() + " "); } return "queue size is " + size + " and the element is " + sb.toString(); } public static void main(String[] args) { Queue<Integer> intQueue = new LinkedQueue<Integer>(); for(int i=0; i<10; i++){ intQueue.in(i); } System.out.println("before out\n " + intQueue); System.out.print("out queue "); for(int i=0; i<10; i++){ System.out.print(intQueue.out()); } System.out.println(""); System.out.println("after out " + intQueue); intQueue.in(1000); System.out.println("first and last is " + intQueue.getFirst() + " " + intQueue.getLast()); System.out.println("1000 in " + intQueue); intQueue.clear(); System.out.println("after clear " + intQueue); } }
before out queue size is 10 and the element is 0 1 2 3 4 5 6 7 8 9 out queue 0123456789 after out queue size is 0 and the element is null first and last is 1000 1000 1000 in queue size is 1 and the element is 1000 after clear queue size is 0 and the element is null
原文地址:http://blog.csdn.net/u010469003/article/details/24771269