📜  使用模板类和循环数组实现动态双端队列

📅  最后修改于: 2021-09-07 03:25:44             🧑  作者: Mango

任务是使用模板类和循环数组实现动态 Deque,具有以下功能:

  • front():从双端队列中获取最前面的项目。
  • back():从双端队列中获取最后一项。
  • push_back(X):在双端队列末尾推送 X。
  • push_front(X):在双端队列开始时推送 X。
  • pop_front():从双端队列的开头删除一个元素。
  • pop_back():从双端队列的末尾删除一个元素
  • empty():检查双端队列是否为空
  • capacity():当前 deque 可以存储的最大元素数
  • size():双端队列中的元素数

下面是分步说明:

  • 最初,双端队列是空的

  • 将 1 插入到 deque 的后面

  • 将元素 2、3 插入到 deque 的后面

  • 在 deque 前面插入 4

  • 将 5 插入到 deque 的后面

  • 从 deque 前面弹出 2 个元素,从 deque 后面弹出 2 个元素

  • 从 deque 前面弹出 1 个元素

方法:这个想法是在每次数组容量已满时将使用的数组大小加倍,并将前一个数组的元素复制到新数组中。请按照以下步骤解决问题:

  • 初始化 4 个变量,比如frontIndexbackIndexsizeVarcapacityVar ,以及一个数组比如arr[]来实现双端队列。
  • 定义一个函数say capacity()来查找当前使用的数组的大小并返回变量capacityVar的值。
  • 定义一个函数say size()来查找双端队列中元素的数量并返回变量sizeVar的值
  • 定义一个函数说满()找到,如果双端队列是否已满,如果sizeVar等于capacityVar返回true。否则,返回false。
  • 定义一个函数say empty()来查找双端队列是否为空,如果frontIndexbackIndex等于-1则返回 true。否则,返回false。
  • 定义一个函数say Front()来打印双端队列的前端元素。如果 deque 不是 empty(),则打印arr[frontIndex]的元素。
  • 定义一个函数say Back()来打印双端队列的最后一个元素。如果 deque 不是 empty() ,则打印arr[BackIndex]的元素。
  • 定义一个函数say push_back(X)在双端队列的末尾插入一个元素:
    • 如果双端队列已满,则将当前数组的大小加倍,并将前一个数组的元素复制到新数组中。
    • 如果 deque 为empty() ,则分配frontIndex = backIndex = 0 ,然后将X分配给arr[frontIndex]arr[backIndex] ,然后将sizeVar增加 1。
    • 否则,更新backIndexbackIndex =(backIndex + 1)%capacityVar然后分配X由一个常用3 [backIndex]和增量sizeVar。
  • 定义一个函数say push_front(X)在双端队列的开头插入一个元素:
    • 如果双端队列已满,则将当前数组的大小加倍,并将前一个数组的元素复制到新数组中。
    • 如果 deque 为empty() ,则分配frontIndex = backIndex = 0 ,然后将X分配给arr[frontIndex]arr[backIndex] ,然后将sizeVar增加 1。
    • 否则,更新frontIndexfrontIndex =(frontIndex-1 + capacityVar)%capacityVar然后分配X由一个常用3 [frontIndex]和增量sizeVar。
  • 定义一个函数say pop_front()来删除 deque 前面的一个元素:
    • 如果双端队列为空,则打印“Underflow”
    • 否则,如果是sizeVar通过一个等于1,则分配-1frontIndexbackIndex两者结合,然后递减sizeVar。
    • 否则,更新frontIndexfrontIndex =(frontIndex + 1)%capacityVar和减量sizeVar由一个。
  • 定义一个函数say pop_back()来删除 deque 前面的一个元素:
    • 如果双端队列为空,则打印“Underflow”
    • 否则,如果是sizeVar通过一个等于1,则分配-1frontIndexbackIndex两者结合,然后递减sizeVar。
    • 否则,更新backIndexbackIndex =(backndex-1 + capacityVar)%capacityVar和减量sizeVar由一个。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Class definition of the deque
template 
class Deque {
 
private:
    // Stores the frontIndex
    int frontIndex;
 
    // Stores the backIndex
    int backIndex;
 
    // Stores the array
    X* arr;
 
    // Stores the size of deque
    int sizeVar;
 
    // Stores the size of array
    int capacityVar = 4;
 
public:
    // Deque class constructor
    Deque()
    {
        arr = new X[capacityVar];
        frontIndex = backIndex = -1;
        sizeVar = 0;
    }
 
    // Function methods
    bool empty();
    bool full();
    void push_back(X x);
    void push_front(X x);
    void pop_front();
    void pop_back();
    X front();
    X back();
    int capacity();
    int size();
};
 
// Function to find the capacity of the deque
template 
int Deque::capacity()
{
    return capacityVar;
}
 
// Function to find the number of elements
// present in deque
template 
int Deque::size() { return sizeVar; }
 
// Function to check if deque is empty or not
template 
bool Deque::empty()
{
    if (frontIndex == -1 && backIndex == -1)
        return true;
    else
        return false;
}
 
// Function to check if deque is full or not
template 
bool Deque::full()
{
    if (sizeVar == capacityVar)
        return true;
    else
        return false;
}
 
// Function to find the front element of the deque
template 
X Deque::front()
{
    // If deque is empty
    if (empty()) {
        cout << "Deque underflow" << endl;
        abort();
    }
    return arr[frontIndex];
}
 
// Function to find the last element of the deque
template 
X Deque::back()
{
    // If deque is empty
    if (empty()) {
        cout << "Deque underflow" << endl;
        abort();
    }
    return arr[backIndex];
}
 
// Function to insert the element
// to the back of the deque
template 
void Deque::push_back(X x)
{
    if (full()) {
 
        // If the deque is full, then
        // double the capacity
        capacityVar = capacityVar * 2;
 
        // Initialize new array of
        // double size
        X* temp = new X[capacityVar];
 
        // Copy the elements of the
        // previous array
        int i = frontIndex;
        int j = 0;
        while (i != backIndex) {
            temp[j] = arr[i];
            i = (i + 1) % sizeVar;
            j++;
        }
        temp[j] = arr[i];
 
        frontIndex = 0;
        backIndex = sizeVar - 1;
 
        // Deallocate the memory
        // of previous array
        delete[] arr;
        arr = temp;
    }
 
    // If size is zero
    if (empty()) {
        frontIndex = backIndex = 0;
        arr[backIndex] = x;
        sizeVar++;
        return;
    }
 
    // Increment back index cyclically
    backIndex = (backIndex + 1) % capacityVar;
    arr[backIndex] = x;
    sizeVar++;
    return;
}
 
// Function to insert the element
// to the front of the deque
template 
void Deque::push_front(X x)
{
    if (full()) {
 
        // If the deque is full, then
        // double the capacity
        capacityVar = capacityVar * 2;
 
        // Initialize new array of
        // double size
        X* temp = new X[capacityVar];
 
        // Copy the elements of the
        // previous array
        int i = frontIndex;
        int j = 0;
        while (i != backIndex) {
            temp[j] = arr[i];
            i = (i + 1) % sizeVar;
            j++;
        }
        temp[j] = arr[i];
 
        frontIndex = 0;
        backIndex = sizeVar - 1;
 
        // Deallocate the memory
        // of previous array
        delete[] arr;
        arr = temp;
    }
 
    // If size is zero
    if (empty()) {
        frontIndex = backIndex = 0;
        arr[backIndex] = x;
        sizeVar++;
        return;
    }
 
    // Decrement front index cyclically
    frontIndex
        = (frontIndex - 1 + capacityVar) % capacityVar;
    arr[frontIndex] = x;
    sizeVar++;
    return;
}
 
// Function to delete the element
// from the front of the deque
template 
void Deque::pop_front()
{
    // If deque is empty
    if (empty()) {
        cout << "Deque underflow" << endl;
        abort();
    }
 
    // If there is only one character
    if (frontIndex == backIndex) {
 
        // Mark deque as empty
        // and decrement sizeVar
        frontIndex = backIndex = -1;
        sizeVar--;
        return;
    }
 
    // Increment frontIndex cyclically
    frontIndex = (frontIndex + 1) % capacityVar;
    sizeVar--;
    return;
}
 
// Function to delete the element
// from the back of the deque
template 
void Deque::pop_back()
{
    // If deque is empty
    if (empty()) {
        cout << "Deque underflow" << endl;
        abort();
    }
 
    // If there is only one character
    if (frontIndex == backIndex) {
 
        // Mark deque as empty
        // and decrement sizeVar
        frontIndex = backIndex = -1;
        sizeVar--;
        return;
    }
 
    // Decrement backIndex cyclically
    backIndex = (backIndex - 1 + capacityVar) % capacityVar;
    sizeVar--;
    return;
}
 
// Driver Code
int main()
{
    // Deque initialization
    Deque q;
 
    // Iterate range [1, 100],
    // push even numbers at the back
    // and push odd numbers at the front
    for (int i = 1; i < 10; i++)
        if (i % 2 == 0)
            q.push_back(i);
        else
            q.push_front(i);
 
    // Print the current capacity
    cout << "Current capacity " << q.capacity() << endl;
 
    // Print the current size
    cout << "Current size " << q.size() << endl;
 
    // Print front elements of deque
    cout << "Front element " << q.front() << endl;
 
    // Print last element of the deque
    cout << "Rear element " << q.back() << endl;
 
    cout << endl;
 
    cout << "Pop an element from front" << endl;
 
    // Pop an element from the front of deque
    q.pop_front();
 
    cout << "Pop an element from back" << endl;
 
    // Pop an element from the back of deque
    q.pop_back();
 
    cout << endl;
 
    // Print the current capacity
    cout << "Current capacity " << q.capacity() << endl;
 
    // Print current size
    cout << "Current size " << q.size() << endl;
 
    // Print front elements of deque
    cout << "Front element " << q.front() << endl;
 
    // Print last element of the deque
    cout << "Rear element " << q.back() << endl;
 
    return 0;
}


输出
Current capacity 16
Current size 9
Front element 9
Rear element 8

Pop an element from front
Pop an element from back

Current capacity 16
Current size 7
Front element 7
Rear element 6

时间复杂度: O(N)
辅助空间: O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live