数据结构和算法(四)队列Queue

队列简介

队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。

这里写图片描述

队列可以使用顺序表和链表实现

ArrayQueue

    public class ArrayQueue<T>{

        private static final int MINIMUM_SIZE = 1024;

        private T[] array = (T[]) new Object[MINIMUM_SIZE];
        private int lastIndex = 0;
        private int firstIndex = 0;

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean offer(T value) {
            if (size() >= array.length)
                grow(size());

            array[lastIndex % array.length] = value;
            lastIndex++;
            return true;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public T poll() {
            int size = lastIndex - firstIndex;
            if (size < 0) return null;

            T t = array[firstIndex % array.length];
            array[firstIndex % array.length] = null;
            firstIndex++;

            size = lastIndex - firstIndex;
            if (size <= 0) {
                // Removed last element
                lastIndex = 0;
                firstIndex = 0;
            }

            int shrinkSize = array.length>>1;
            if (shrinkSize >= MINIMUM_SIZE && size < shrinkSize)
                shrink();

            return t;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public T peek() {
            return array[firstIndex % array.length];
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean remove(T value) {
            for (int i=0; i < array.length; i++) {
                T obj = array[i];
                // if obj is null, it should return false (not NPE)
                if (value.equals(obj)) return remove(i);
            }
            return false;
        }

        private boolean remove(int index) {
            if (index<0 || index >= array.length) return false;
            if (index==firstIndex) return (poll()!=null);

            int adjIndex = index % array.length;
            int adjLastIndex = (lastIndex-1) % array.length;
            if (adjIndex != adjLastIndex) {
                // Shift the array down one spot
                System.arraycopy(array, index+1, array, index, (array.length - (index+1)));
                if (adjLastIndex < firstIndex) {
                    //Wrapped around array
                    array[array.length-1] = array[0];
                    System.arraycopy(array, 1, array, 0, firstIndex-1);
                }
            }
            array[adjLastIndex] = null;

            int shrinkSize = array.length>>1;
            if (shrinkSize >= MINIMUM_SIZE && size() < shrinkSize)
                shrink();

            lastIndex--;
            return true;
        }

        // Grow the array by 50% and rearrange to make sequential
        private void grow(int size) {
            int growSize = (size + (size<<1));
            T[] temp = (T[]) new Object[growSize];
            // Since the array can wrap around, make sure you grab the first chunk 
            int adjLast = lastIndex % array.length;
            if (adjLast < firstIndex) {
                System.arraycopy(array, 0, temp, array.length-adjLast, adjLast+1);
            }
            // Copy the remaining
            System.arraycopy(array, firstIndex, temp, 0, array.length-firstIndex);
            array = null;
            array = temp;
            lastIndex = (lastIndex - firstIndex);
            firstIndex = 0;
        }

        // Shrink the array by 50% and rearrang e tomake sequential
        private void shrink() {
            int shrinkSize = array.length>>1;
            T[] temp = (T[]) new Object[shrinkSize];
            // Since the array can wrap around, make sure you grab the first chunk 
            int adjLast = lastIndex % array.length;
            int endIndex = (lastIndex>array.length)?array.length:lastIndex;
            if (adjLast <= firstIndex) {
                System.arraycopy(array, 0, temp, array.length-firstIndex, adjLast);
            }
            // Copy the remaining
            System.arraycopy(array, firstIndex, temp, 0, endIndex-firstIndex);
            array = null;
            array = temp;
            lastIndex = (lastIndex - firstIndex);
            firstIndex = 0;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void clear() {
            firstIndex = 0;
            lastIndex = 0;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean contains(T value) {
            for (int i=0; i < array.length; i++) {
                T obj = array[i];
                // if obj is null, it should return false (not NPE)
                if (value.equals(obj)) return true;
            }
            return false;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean validate() {
            if (size()==0) return true;

            int localSize = 0;
            int realFirst = firstIndex;
            if (firstIndex>array.length) 
                realFirst = firstIndex%array.length;
            int realLast = lastIndex;
            if (lastIndex>array.length) 
                realLast = lastIndex%array.length;
            for (int i=0; i<array.length; i++) {
                T t = array[i];
                if ((realFirst==realLast) || 
                    (realFirst<realLast && (i>=realFirst && i<realLast)) || 
                    (realLast<realFirst && (i<realLast || i>=realFirst))
                ) {
                    if (t==null)
                        return false;
                    localSize++;
                } else {
                    if (t!=null)
                        return false;
                }
            }
            return (localSize==size());
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public int size() {
            return lastIndex - firstIndex;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public java.util.Queue<T> toQueue() {
            return (new JavaCompatibleArrayQueue<T>(this));
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public java.util.Collection<T> toCollection() {
            return (new JavaCompatibleArrayQueue<T>(this));
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            for (int i = lastIndex - 1; i >= firstIndex; i--) {
                builder.append(array[i%array.length]).append(", ");
            }
            return builder.toString();
        }
    }

LinkedQueue

public static class LinkedQueue<T>{

        private Node<T> head = null;
        private Node<T> tail = null;
        private int size = 0;

        public LinkedQueue() {
            head = null;
            tail = null;
            size = 0;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean offer(T value) {
            return add(new Node<T>(value));
        }

        /**
         * Enqueue the node in the queue.
         * 
         * @param node
         *            to enqueue.
         */
        private boolean add(Node<T> node) {
            if (head == null) {
                head = node;
                tail = node;
            } else {
                Node<T> oldHead = head;
                head = node;
                node.next = oldHead;
                oldHead.prev = node;
            }
            size++;
            return true;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public T poll() {
            T result = null;
            if (tail != null) {
                result = tail.value;

                Node<T> prev = tail.prev;
                if (prev != null) {
                    prev.next = null;
                    tail = prev;
                } else {
                    head = null;
                    tail = null;
                }
                size--;
            }
            return result;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public T peek() {
            return (tail!=null)?tail.value:null;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean remove(T value) {
            // Find the node
            Node<T> node = head;
            while (node != null && (!node.value.equals(value))) {
                node = node.next;
            }
            if (node == null) return false;
            return remove(node);
        }

        private boolean remove(Node<T> node) {
            // Update the tail, if needed
            if (node.equals(tail))
                tail = node.prev;

            Node<T> prev = node.prev;
            Node<T> next = node.next;
            if (prev != null && next != null) {
                prev.next = next;
                next.prev = prev;
            } else if (prev != null && next == null) {
                prev.next = null;
            } else if (prev == null && next != null) {
                // Node is the head
                next.prev = null;
                head = next;
            } else {
                // prev==null && next==null
                head = null;
            }
            size--;
            return true;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void clear() {
            head = null;
            size = 0;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean contains(T value) {
            if (head == null)
                return false;

            Node<T> node = head;
            while (node != null) {
                if (node.value.equals(value))
                    return true;
                node = node.next;
            }
            return false;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public int size() {
            return size;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean validate() {
            java.util.Set<T> keys = new java.util.HashSet<T>();
            Node<T> node = head;
            if (node!=null) {
                keys.add(node.value);
                if (node.prev!=null) return false;
                Node<T> child = node.next;
                while (child!=null) {
                    if (!validate(child,keys)) return false;
                    child = child.next;
                }
            }
            return (keys.size()==size());
        }

        private boolean validate(Node<T> node, java.util.Set<T> keys) {
            if (node.value==null) return false;
            keys.add(node.value);

            Node<T> child = node.next;
            if (child!=null) {
                if (!child.prev.equals(node)) return false;
                if (!validate(child,keys)) return false;
            } else {
                if (!node.equals(tail)) return false;
            }
            return true;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public java.util.Queue<T> toQueue() {
            return (new JavaCompatibleLinkedQueue<T>(this));
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public java.util.Collection<T> toCollection() {
            return (new JavaCompatibleLinkedQueue<T>(this));
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            Node<T> node = head;
            while (node != null) {
                builder.append(node.value).append(", ");
                node = node.next;
            }
            return builder.toString();
        }

        private static class Node<T> {

            private T value = null;
            private Node<T> prev = null;
            private Node<T> next = null;

            private Node(T value) {
                this.value = value;
            }

            /**
             * {@inheritDoc}
             */
            @Override
            public String toString() {
                return "value=" + value + " previous=" + ((prev != null) ? prev.value : "NULL") + " next=" + ((next != null) ? next.value : "NULL");
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值