java_queue

队列是一种特殊的线性表,先进先出(first in first out)FIFO,它只允许在表的前端(front)进行删除操作,只允许在表的后端(rear)进行插入操作。

实际应用:排队等待公交车,银行或者超市里的等待列队

出现假溢出的时候的一般解决方法:

一是将队列元素向前平移,对应的队列的顺序存储结构及实现中的a实现

二循环队列,对应的循环队列实现

1.队列的顺序存储结构及实现

a.没有控制队列容量大小的普通队列,数组移位实现(无假溢出现象

package collectionsFramework.queue;

/** 
 * @Package collectionsFramework.queue

 * @ClassName: SequenceQueue

 * @Description: TODO(这里用一句话描述这个类的作用)

 * @author andy

 * @date 2013-11-21 下午05:26:10

 */
public class SequenceQueue<T> {
    //队列个数
    private int size;
    //装载元素的数组
    private Object[] elementData;
    //默认容量大小
    private int defaultCapacity = 16;
    //容量大小
    private int capacity;
    //增量大小
    private int incrementCapacity;
    
    public SequenceQueue(){
        elementData = new Object[defaultCapacity];
    }
    
    public SequenceQueue(int capacity){
        this.capacity = capacity;
        elementData = new Object[capacity];
        
    }
    
    public SequenceQueue(int capacity,int incrementCapacity){
        this(capacity);
        this.incrementCapacity = incrementCapacity;
    }
    
    //入列
    public synchronized T add(T element){
        if(null == element){
            return null;
        }
        boolean flag = true;
        try {
            ensureCapacity();
        } catch (Exception e) {
            try {
                ensureCapacity();
            } catch (Exception e1) {
                flag = false;
                try {
                    throw new Exception("第二次数组扩容失败!");
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            } 
        }
        if(flag){
            elementData[size++] = element;
            return element;
        }
        
        return null;
    }
    
    //出列
    public synchronized T poll(){
        if(size == 0){
            return null;
        }
        Object[] oldData = elementData;
        elementData = new Object[elementData.length];
        try {
            System.arraycopy(oldData, 1, elementData, 0, elementData.length - 1);
        } catch (Exception e) {
            try {
                throw new Exception("移除元素,数组元素往前移植时出错");
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
            
        }
        size--;
        return (T)oldData[0];
        
    }
    
    //移除头部元素,但不删除
    public synchronized T peek(){
        if(0 == size){
            return null;
        }
        return (T)elementData[0];
    }
    
    //确保容量够
    private synchronized void ensureCapacity() {
        if(size == elementData.length){
            int length = 0;
            if(incrementCapacity > 0){
                length = elementData.length + length;
            }else{
                length = elementData.length<<1;
            }
            Object[] oldData = elementData;
            elementData = new Object[length];
            try {
                System.arraycopy(oldData, 0, elementData, 0, size-1);
            } catch (Exception e) {
                try {
                    throw new Exception("第一次数组扩容失败!");
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
    
    public String toString() {
        if (0==size) {
            return "[]";
        } else {
            StringBuilder sb = new StringBuilder("[");
            for (int i = 0; i < size; i++) {
                sb.append(elementData[i].toString() + ", ");
            }
            int len = sb.length();
            return sb.delete(len - 2, len).append("]").toString();
        }
    }
    
    public static void main(String[] args) {
        SequenceQueue<String> queue = new SequenceQueue<String>(10);
        for(int i = 0; i<100; i++){
            System.out.println("元素:" + queue.add("a" + i) + " 入列");
            System.out.println("字符串:" + queue);
            if(queue.size == queue.capacity){
                System.out.println("已经有"+queue.capacity+"个未运行的任务数");
                System.out.println("元素:" + queue.poll() + "---------出列");
            }
        }
        while(queue.size != 0){
            System.out.println("字符串:" + queue);
            System.out.println("元素:" + queue.poll() + " 出列");
        }
    }
}
View Code

b.控制了容量大小的队列(会有假溢出现象)

package collectionsFramework.queue;

import java.util.Arrays;

/**
 * @Package collectionsFramework.queue
 * 
 * @ClassName: SequenceQueue2
 * 
 * @Description: TODO(这里用一句话描述这个类的作用)
 * 
 * @author andy
 * 
 * @date 2013-11-24 下午06:52:39
 */
public class SequenceQueue3<T> {
    private int DEFAULT_SIZE = 10;
    // 保存数组的长度。
    private int capacity;
    // 定义一个数组用于保存顺序队列的元素
    private Object[] elementData;
    // 保存顺序队列中元素的当前个数
    private int front = 0;
    private int rear = 0;

    // 以默认数组长度创建空顺序队列
    public SequenceQueue3() {
        capacity = DEFAULT_SIZE;
        elementData = new Object[capacity];
    }

    // 以一个初始化元素来创建顺序队列
    public SequenceQueue3(T element) {
        this();
        elementData[0] = element;
        rear++;
    }

    /**
     * 以指定长度的数组来创建顺序队列
     * 
     * @param element
     *            指定顺序队列中第一个元素
     * @param initSize
     *            指定顺序队列底层数组的长度
     */
    public SequenceQueue3(T element, int initSize) {
        this.capacity = initSize;
        elementData = new Object[capacity];
        elementData[0] = element;
        rear++;
    }

    // 获取顺序队列的大小
    public int length() {
        return rear - front;
    }

    // 插入队列
    public T add(T element) {
        if (rear > capacity - 1) {
            throw new IndexOutOfBoundsException("队列已满的异常");
        }
        elementData[rear++] = element;
        return element;
    }

    // 移除队列
    public T remove() {
        if (empty()) {
            throw new IndexOutOfBoundsException("空队列异常");
        }
        // 保留队列的rear端的元素的值
        T oldValue = (T) elementData[front];
        // 释放队列的rear端的元素
        elementData[front++] = null;
        return oldValue;
    }

    // 返回队列顶元素,但不删除队列顶元素
    public T element() {
        if (empty()) {
            throw new IndexOutOfBoundsException("空队列异常");
        }
        return (T) elementData[front];
    }

    // 判断顺序队列是否为空队列
    public boolean empty() {
        return rear == front;
    }

    // 清空顺序队列
    public void clear() {
        // 将底层数组所有元素赋为null
        Arrays.fill(elementData, null);
        front = 0;
        rear = 0;
    }

    public String toString() {
        if (empty()) {
            return "[]";
        } else {
            StringBuilder sb = new StringBuilder("[");
            for (int i = front; i < rear; i++) {
                sb.append(elementData[i].toString() + ", ");
            }
            int len = sb.length();
            return sb.delete(len - 2, len).append("]").toString();
        }
    }

    public static void main(String[] args) {
        SequenceQueue3<String> queue = new SequenceQueue3<String>();
        for (int i = 0; i < queue.capacity; i++) {
            System.out.println("元素:" + queue.add("a" + i) + "入列");
        }

        /*int j = 0;
        while (!queue.empty()) {
            j++;
            System.out.println("元素:" + queue.remove()
                    + "+++++++++++++++++=====出列");
            if (!queue.empty()) {
                System.out.println("元素:" + queue.add("j" + j) + "入列");
            }
            if (100 == j) {
                break;
            }
        }*/

        while (!queue.empty()) {
            System.out.println("元素:" + queue.remove() + "出列");
        }
    }
}
View Code

2.队列的链式存储结构及实现

package collectionsFramework.queue;

/**
 * @Package collectionsFramework.queue
 * 
 * @ClassName: LinkQueue
 * 
 * @Description: TODO(这里用一句话描述这个类的作用)
 * 
 * @author andy
 * 
 * @date 2013-11-24 下午10:30:26
 */
public class LinkQueue<T> {
    // 定义一个内部类Node,Node实例代表链队列的节点。
    private class Node {
        // 保存节点的数据
        private T data;
        // 指向下个节点的引用
        private Node next;

        // 无参数的构造器
        public Node() {
        }

        // 初始化全部属性的构造器
        public Node(T data, Node next) {
            this.data = data;
            this.next = next;
        }
    }

    // 保存该链队列的头节点
    private Node front;
    // 保存该链队列的尾节点
    private Node rear;
    // 保存该链队列中已包含的节点数
    private int size;

    // 创建空链队列
    public LinkQueue() {
        // 空链队列,front和rear都是null
        front = null;
        rear = null;
    }

    // 返回链队列的长度
    public int length() {
        return size;
    }

    // 将新元素加入队列
    public T add(T element) {
        if (size == 0) {
            front = new Node(element, null);
            rear = front;
        } else {
            //rear = new Node(element, null);//这些写虽然有下一个结点,但是当前结点对下个结点的引用都是空的
            //创建新节点  
            Node newNode = new Node(element , null);  
            //让尾节点的next指向新增的节点  
            rear.next = newNode;  
            //以新节点作为新的尾节点  
            rear = newNode;  
        }
        size++;
        return element;

    }

    // 访问链式队列中最后一个元素
    public T element() {
        return rear.data;
    }

    // 判断链式队列是否为空队列
    public boolean empty() {
        return size == 0;
    }

    // 删除队列front端的元素
    public T remove() {
        if (0 != size) {
            // 保存之前的前端结点
            Node oldFront = front;
            // 前端结点移除就没有了,所以将前端的下个节点设置为新的前端结点,并把将要移除的前端结点的对下个结点的引用设为null
            Node newfront = front.next;
            front.next = null;
            front = newfront;
            size--;
            return oldFront.data;
        } else {
            return null;
        }
    }

    // 清空链队列
    public void clear() {
        // 将front、rear两个节点赋为null
        front = null;
        rear = null;
        size = 0;
    }

    public String toString() {
        // 链队列为空链队列时
        if (empty()) {
            return "[]";
        } else {
            StringBuilder sb = new StringBuilder("[");
            for (Node current = front; current != null; current = current.next) {
                sb.append(current.data.toString() + ", ");
            }
            int len = sb.length();
            return sb.delete(len - 2, len).append("]").toString();
        }
    }
    
    public static void main(String[] args) {
        LinkQueue<String> queue = new LinkQueue<String>();
        for(int i = 0; i<100; i++){
            System.out.println("元素:" + queue.add("a" + i) + " 入列");
            System.out.println("字符串表示:" + queue);
            if(queue.size == 20){
                System.out.println("已经有"+"20"+"个未运行的任务数");
                System.out.println("元素:" + queue.remove() + "---------出列");
            }
        }
        //queue.clear();
        while(queue.size != 0){System.out.println("字符串表示:" + queue);
            System.out.println("元素:" + queue.remove() + " 出列");
        }
    }
}
View Code

3.循环队列(顺序结构存储实现)

package collectionsFramework.queue;

/**
 * @Package collectionsFramework.queue
 * 
 * @ClassName: LoopQueue
 * 
 * @Description: TODO(这里用一句话描述这个类的作用)
 * 
 * @author andy
 * 
 * @date 2013-11-24 下午11:32:52
 */
public class LoopQueue<T> {
    private int DEFAULT_SIZE = 10;
    // 保存数组的长度。
    private int capacity;
    // 定义一个数组用于保存循环队列的元素
    private Object[] elementData;

    private int front = -1;
    private int rear = -1;

    // 以默认数组长度创建空循环队列
    public LoopQueue() {
        capacity = DEFAULT_SIZE;
        elementData = new Object[capacity];
    }

    // 判断是否为空
    private boolean empty() {
        return front == -1;
    }

    // 判断栈是否满了
    public boolean isFull() {
        return (rear + 1) % capacity == front;
    }

    // 置空
    public void clear() {
        front = rear = -1;
    }

    
     //元素个数
    /*public int length() {
        if (empty()) {
            return 0;
        }
        return (rear - front + capacity) % capacity;
    }*/
     

    public int length() {// 队列长度
        if(empty()){
            return 0;
        }
        
        if (rear >= front)
            return rear - front + 1;
        else
            return capacity - (front - rear) + 1;
    }

    // 插入队列
    public T add(T element) {
        if (isFull()) {
            System.out.println("队列已经满了");
            return null;
        }

        if (empty()) {
            front = rear = 0;
        } else {
            rear = (rear + 1) % capacity;
        }
        elementData[rear] = element;
        return element;
    }

    // 移除队列顶部元素
    public T remove() {
        if (empty()) {
            System.out.println("空队列");
            throw new IndexOutOfBoundsException("空队列异常");
        }
        T oldData = (T) elementData[front];
        elementData[front] = null;
        if (front == rear) {
            clear();
            return oldData;
        }
        front = (front + 1) % capacity;
        return oldData;
    }

    // 返回队列顶部元素,但不删除元素
    public T element() {
        if (empty()) {
            return null;
        }
        return (T) elementData[front + 1];
    }
    
    public String toString() {// 打印所有元素
        if (empty()) {
            return "[]";
        }else{
            StringBuilder sb = new StringBuilder("[");
            int i = front;
            int j = 0;
            while(j < length()){
                sb.append(elementData[i].toString() + ", ");
                i = (i + 1) % capacity;
                j++;
            }
            /*for (int j = 0; j < length(); i = (i + 1) % capacity, j++){
                sb.append(elementData[i].toString() + ", ");
            }*/
            int len = sb.length();
            return sb.delete(len - 2, len).append("]").toString();
        }
    }
    
    public static void main(String[] args) {
        LoopQueue<String> queue = new LoopQueue<String>();
        for (int i = 0; i < 100; i++) {
            System.out.println("元素:" + queue.add("a" + i) + " 入列");
            System.out.println("字符串表示:" + queue);
            if(queue.length() == queue.capacity){
                System.out.println("元素:"+queue.remove() + " +++++++++++++出列"); 
            }
            //System.out.println("元素长度:" + queue.length());
            
        }
         //queue.clear(); 
         while(queue.length() != 0){ 
             System.out.println("字符串表示:" + queue);
             System.out.println("元素:"+queue.remove() + " 出列");
            
         } 
    }

}
View Code

 

 

 

 

 

posted on 2013-11-23 19:45  lovebeauty  阅读(301)  评论(0编辑  收藏  举报

导航