• 环形队列设计


    两道环形队列设计的题。

    LeetCode 622. Design Circular Queue
    LeetCode 641. Design Circular Deque

    题目描述

    一道题是环形 queue 的设计,circular queue is also called "Ring Buffer";另一道是环形 deque 的设计。给出了 API 要求给出实现。

    解题思路

    两道题实际上是一样的,开辟对应大小的缓冲区,然后环形的话使用取余操作来实现即可。
    这里我们使用 head & tail 指向首尾元素,并额外多分配一个元素的空间作为哨兵,用于区分空队列和满队列。

    参考代码

    这里我们只给出 deque 的实现代码,因为 queue 实际上是限定了只能使用 deque 的部分功能,queue 的实现只需要截取 deque 对应部分的实现即可。

    /*
     * @lc app=leetcode id=641 lang=cpp
     *
     * [641] Design Circular Deque
     */
    
    // @lc code=start
    class MyCircularDeque {
        int* data;
        int cap;
        int head, tail;
    public:
        /** Initialize your data structure here. Set the size of the deque to be k. */
        MyCircularDeque(int k) :
            data(new int[k+1]), cap(k+1), head(0), tail(k) {
        }
        ~MyCircularDeque() {
            delete[] data;
        }
    
        /** Adds an item at the front of Deque. Return true if the operation is successful. */
        bool insertFront(int value) {
            if (isFull()) {
                return false;
            }
            head = (head - 1 + cap) % cap;
            data[head] = value;
            return true;
        }
    
        /** Adds an item at the rear of Deque. Return true if the operation is successful. */
        bool insertLast(int value) {
            if (isFull()) {
                return false;
            }
            tail = (tail + 1) % cap;
            data[tail] = value;
            return true;
        }
    
        /** Deletes an item from the front of Deque. Return true if the operation is successful. */
        bool deleteFront() {
            if (isEmpty()) {
                return false;
            }
            head = (head + 1) % cap;
            return true;
        }
    
        /** Deletes an item from the rear of Deque. Return true if the operation is successful. */
        bool deleteLast() {
            if (isEmpty()) {
                return false;
            }
            tail = (tail - 1 + cap) % cap;
            return true;
        }
    
        /** Get the front item from the deque. */
        int getFront() {
            if (isEmpty()) {
                return -1;
            }
            return data[head];
        }
    
        /** Get the last item from the deque. */
        int getRear() {
            if (isEmpty()) {
                return -1;
            }
            return data[tail];
        }
    
        /** Checks whether the circular deque is empty or not. */
        bool isEmpty() {
            return head == (tail + 1) % cap;
        }
    
        /** Checks whether the circular deque is full or not. */
        bool isFull() {
            return head == (tail + 2) % cap;
        }
    }; // AC
    
    /**
     * Your MyCircularDeque object will be instantiated and called as such:
     * MyCircularDeque* obj = new MyCircularDeque(k);
     * bool param_1 = obj->insertFront(value);
     * bool param_2 = obj->insertLast(value);
     * bool param_3 = obj->deleteFront();
     * bool param_4 = obj->deleteLast();
     * int param_5 = obj->getFront();
     * int param_6 = obj->getRear();
     * bool param_7 = obj->isEmpty();
     * bool param_8 = obj->isFull();
     */
    // @lc code=end
    

    拓展延伸

    C++ 中的 queue 的实现是什么样的?

    C++ 中的 queue 和 stack 一样,都并不是某一特定的类型,而是一个“适配器”。实际上,queue 的底层可以是一个双端队列 deque,也可以是一个双链表,默认是deque。

    deque 对内存的管理是以页为单位分配数组,页内的元素在两端的操作都可以像普通数组一样操作;页与页之间并不是连续分配,而是使用链表或者索引表来管理,两端的 push/pop 操作可能触发页分配和页回收。通过这种策略,回收了空闲内存,也就是 “make use of the spaces in front of the queue”,当然 deque 也做到了 “make use of spaces in rear of the queue”。

  • 相关阅读:
    Django入门
    html语言
    elasticsearch基本接口使用
    linux随笔
    mysql基础操作
    mysql存储引擎
    MySQL字符集
    并发编程之多进程
    异常处理
    socket编程
  • 原文地址:https://www.cnblogs.com/zhcpku/p/14534318.html
Copyright © 2020-2023  润新知