zoukankan      html  css  js  c++  java
  • 队列

    抽象数据类型描述:

    public interface Queue {
        
        // 先进先出只能从队首删除、队尾插入
        public void clear();
        public void enqueue(Object obj);        // 在队尾插入一个新元素
        public Object dequeue();        // 删除并返回队首元素
        
        public boolean isEmpty();
        public int size();
        public Object peek();        // 返回队首元素
        
    }

    数组实现队列:

    public class ArrayQueue implements Queue {
    
        private static final int DEFAULT_SIZE = 10;
        private Object[] array;
        private int front;        // 指向队首元素
        private int rear;        // 指向队尾元素的后继位置
        private int count;
    
        // 构造方法,构造队列、初始化
        public ArrayQueue() {
            array = new Object[DEFAULT_SIZE];
            front = rear = count = 0;
        }
    
        public void clear() {
            for (int i = 0; i < array.length; i++) {
                array[i] = null;
                front = rear = count = 0;
            }
        }
    
        public Object dequeue() {
            if (count == 0) {
                throw new IllegalStateException();
            }
            Object obj = array[front];
            array[front++] = null;        // 队首指针递增
            if (front == array.length) {
                front = 0;
            }
            count--;
            return obj;
        }
        
        /* 
         * 因为front=0时队列不一定为空,rear = array.length时队列不一定放满了。例如当rear = 
         * array.length时,front=3,(array[0]、、array[1]、array[2]这3个元素已经删除
         * front才会移动到3)     * 
         * 
         * */
        public void enqueue(Object obj) {
            if (count == array.length) {
                expand();
            }
            array[rear++] = obj;        // 队尾指针递增
            if (rear == array.length) {
                rear = 0;
            }
            count++;
        }
    
        /*
         * 不论经过多少次的增加、删除,front与rear的具体位置在 哪里,最后当循环数组(队列)
         * 放满的时候:front = rear ,front + i其实就是将循环队列“拉直”,然后我们再给
         * front赋值0,rear赋值array.length。当我们把数组元素复制到新数组之后队首位置就
         * 在 新数组的左端啦。
         *  
         */
        private void expand() {
            Object[] newArray = new Object[2 * array.length];
            for (int i = 0; i < count; i++) {
                newArray[i] = array[(front + i) % array.length];
            }
            front = 0;
            rear = array.length;
            array = newArray;
        }
    
        public boolean isEmpty() {
            return count == 0;
        }
    
        public Object peek() {
            if (count ==0) {
                throw new IllegalStateException();
            }
            return array[front];
        }
    
        public int size() {
            return count;
        }
        
        // 总是从头开始
        public String toString() {
            String buf = new String("[ ");
            for (int i = 0; i < count; i++) {
                if (i > 0) {
                    buf += ", ";
                }
                buf += array[(front + i) % array.length].toString();
            }
            buf += " ]";
            return buf;
        }
    
    }

    单向链表实现队列:

    public class LinkedQueue implements Queue {
        
        // 链表节点类
        private static class SLLNode {
            private Object data;
            private SLLNode next;
    
            public SLLNode() {
    
            }
    
            public SLLNode(Object data) {
                this.data = data;
            }
    
            public SLLNode(Object data, SLLNode next) {
                this.data = data;
                this.next = next;
            }
    
            public Object getData() {
                return data;
            }
    
            public void setData(Object data) {
                this.data = data;
            }
    
            public SLLNode getNext() {
                return next;
            }
    
            public void setNext(SLLNode next) {
                this.next = next;
            }
    
            public String toString() {
                return data.toString();
            }
        }
        
        private SLLNode front;        // 指向单向链表第一个节点的引用
        private SLLNode rear;        // 指向单向链表最后一个节点的引用
        private int count;
        
        public LinkedQueue () {
            clear();
        }
        
        public void clear() {
            front = rear = null;
            count = 0;
        }
    
        public Object dequeue() {
            if (count == 0) {
                throw new IllegalStateException();
            }
            Object obj = front.data;
            front = front.next;
            // 当前front没有了后继元素(即队列只剩下一个元素),删除后链表为空,队列为空
            if (front == null) {
                rear = null;
            }
            count --;
            return obj;
        }
    
        public void enqueue(Object obj) {
            SLLNode temp = new SLLNode(obj, null);
            if (this.isEmpty()) {        //队列为空
                front = temp;
            } else {
                rear.next = temp;
            }
            rear = temp;
            count ++;
        }
    
        public boolean isEmpty() {
            return count == 0;
            // return rear == null;
        }
    
        public Object peek() {
            if (this.isEmpty()) {
                throw new IllegalStateException();
            }
            return front.data;
        }
    
        public int size() {
            return count;
        }
        
        public String toString() {
            String buf = new String("[ ");
            for (SLLNode curr = front; curr != null; curr = curr.next) {
                if (curr != front) {
                    buf += ", ";
                }
                buf += curr.data.toString();
            }
            buf += " ]";
            return buf;
        }
    
    }

    测试类:

    public class QueueTest {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            Queue qa = new ArrayQueue();
            int[] array = new int[]{1,2,3,4,5,6,7,8,9};
            qa.enqueue("a");
            qa.enqueue(1);
            qa.enqueue(array);
            qa.enqueue(array[3]);
            qa.enqueue(array.length);
            qa.enqueue("6");
            System.out.println(qa.toString());
            qa.dequeue();
    //        qa.dequeue();
            System.out.println(qa.toString());
            System.out.println(qa.size());
            
            Queue ql = new LinkedQueue();
            ql.enqueue(array);
            ql.enqueue(array.length);
            ql.enqueue(array.hashCode());
            System.out.println(ql.toString());
        }
    
    }

    结果:

    [ a, 1, [I@1fb8ee3, 4, 9, 6 ]
    [ 1, [I@1fb8ee3, 4, 9, 6 ]
    5
    [ [I@1fb8ee3, 9, 33263331 ]
  • 相关阅读:
    关于aspx消除源代码的第一行空行(一步搞定!!!)
    考虑
    一段时间没来园子了
    随便写写
    自考群网站功能说明
    打开一个别人的代码遇到的问题
    i7 4790 z97ar ssd 固态硬盘 装机的一些经历
    我编程遇到的问题,解决方法与大家分享
    学习,学习,还是学习
    准备考试
  • 原文地址:https://www.cnblogs.com/zhangpeng201211/p/2410969.html
Copyright © 2011-2022 走看看