zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    《Java TCP/IP Socket 编程 》读书笔记之十一:深入剖析socket——TCP套接字的生命周期
    c++实现二分查找
    hadoop序列化机制与java序列化机制对比
    C、C++中“*”操作符和“后++”操作符的优先级
    poj2774之最长公共子串
    Python之美[从菜鸟到高手]--urlparse源码分析
    (程序员面试题)字符串处理之寻找最大不重复子串
    hdu 4782 Beautiful Soupz
    教程Xcode 下编译发布与提交App到AppStore
    云端的ABAP Restful服务开发
  • 原文地址:https://www.cnblogs.com/o-andy-o/p/3439348.html
Copyright © 2011-2022 走看看