美文网首页
【算法】使用数组实现队列

【算法】使用数组实现队列

作者: 李翾 | 来源:发表于2019-04-01 10:36 被阅读0次

    众所周知,队列是一种先进先出(First-in-first-out 简称FIFO)数据结构。

    为了实现队列,我们​​可以使用动态数组和指向队列头部的索引。

    如上所述,队列应该支持两个操作:enqueue和dequeue。Enqueue会向队列追加一个新元素,而dequeue会删除第一个元素。所以我们需要一个索引来指出起点。

    代码如下:

    class MyCircularQueue {
           final int[] a;
            int front, rear = -1, len = 0;
    
            public MyCircularQueue(int k) { a = new int[k];}
    
            public boolean enQueue(int val) {
                if (!isFull()) {
                    rear = (rear + 1) % a.length;
                    a[rear] = val;
                    len++;
                    return true;
                } else return false;
            }
    
            public boolean deQueue() {
                if (!isEmpty()) {
                    front = (front + 1) % a.length;
                    len--;
                    return true;
                } else return false;
            } 
    
            public int Front() { return isEmpty() ? -1 : a[front];}
    
            public int Rear() {return isEmpty() ? -1 : a[rear];}
    
            public boolean isEmpty() { return len == 0;}
    
            public boolean isFull() { return len == a.length;}
    
    }
    
    

    上面的代码有个问题就是,随着p_start 增加,空间的浪费。对此,我们进行优化,使用循环的队列(Circular Queue)代码如下:

    class MyCircularQueue {
        
        private int[] data;
        private int head;
        private int tail;
        private int size;
    
        /** Initialize your data structure here. Set the size of the queue to be k. */
        public MyCircularQueue(int k) {
            data = new int[k];
            head = -1;
            tail = -1;
            size = k;
        }
        
        /** Insert an element into the circular queue. Return true if the operation is successful. */
        public boolean enQueue(int value) {
            if (isFull() == true) {
                return false;
            }
            if (isEmpty() == true) {
                head = 0;
            }
            tail = (tail + 1) % size;
            data[tail] = value;
            return true;
        }
        
        /** Delete an element from the circular queue. Return true if the operation is successful. */
        public boolean deQueue() {
            if (isEmpty() == true) {
                return false;
            }
            if (head == tail) {
                head = -1;
                tail = -1;
                return true;
            }
            head = (head + 1) % size;
            return true;
        }
        
        /** Get the front item from the queue. */
        public int Front() {
            if (isEmpty() == true) {
                return -1;
            }
            return data[head];
        }
        
        /** Get the last item from the queue. */
        public int Rear() {
            if (isEmpty() == true) {
                return -1;
            }
            return data[tail];
        }
        
        /** Checks whether the circular queue is empty or not. */
        public boolean isEmpty() {
            return head == -1;
        }
        
        /** Checks whether the circular queue is full or not. */
        public boolean isFull() {
            return ((tail + 1) % size) == head;
        }
    }
    
    /**
     * Your MyCircularQueue object will be instantiated and called as such:
     * MyCircularQueue obj = new MyCircularQueue(k);
     * boolean param_1 = obj.enQueue(value);
     * boolean param_2 = obj.deQueue();
     * int param_3 = obj.Front();
     * int param_4 = obj.Rear();
     * boolean param_5 = obj.isEmpty();
     * boolean param_6 = obj.isFull();
     */
    

    原理就是:使用固定大小的数组(a fixed-size array)和两个变量(two pointers)-head 指示起始位置和 tail 指示结束位置,初始化时head 和tail 均为-1,入队(enQueue)的时候(tail+1)% fixed-size,出队(deQueue)的时候(head+1)% fixed-size,head == 1时候队列为空,((tail + 1) % size) == head时候队列满了。

    很多高级语言,都有内置的队列库,所以我们不需要重复造轮子(reinvent the whell),比如Java

    // "static void main" must be defined in a public class.
    public class Main {
        public static void main(String[] args) {
            // 1. Initialize a queue.
            Queue<Integer> q = new LinkedList();
            // 2. Get the first element - return null if queue is empty.
            System.out.println("The first element is: " + q.peek());
            // 3. Push new element.
            q.offer(5);
            q.offer(13);
            q.offer(8);
            q.offer(6);
            // 4. Pop an element.
            q.poll();
            // 5. Get the first element.
            System.out.println("The first element is: " + q.peek());
            // 7. Get the size of the queue.
            System.out.println("The size is: " + q.size());
        }
    }
    

    相关文章

      网友评论

          本文标题:【算法】使用数组实现队列

          本文链接:https://www.haomeiwen.com/subject/hmogvqtx.html