C++STL之双端队列deque

一说到队列,大家多数人和我一样,第一反应是FIFO原则。
那么双端队列就是一个方向(头或者尾)就可以进也可以出,听起来我们的双端队列是一种具有队列和栈的性质的数据结构。是一种线性的数据结构,相比list增加 [] 运算符重载。
大概长这个样子:
在这里插入图片描述
实际上,在内存中这不是他的真实模样,比这个要复杂的多。

一、双端队列deque的基本使用:

#include <iostream>
#include <deque>
 
int main()
{
    // Create a deque containing integers
    std::deque<int> d = {7, 5, 16, 8};
 
    // Add an integer to the beginning and end of the deque
    d.push_front(13);
    d.push_back(25);
 
    // Iterate and print values of deque
    for(int n : d) {
        std::cout << n << '\n';
    }
}

二、deque的特点: 本文重点内容

  1. 使用的时候,底层默认只开辟两个元素,一维是个数组(vector),这个一位数组中保存着一段缓存区(数组)地址,也就是一个指针;

  2. 二维是个缓冲区,实际上是个数组,长度是确定的,但是二维一开始开辟多大呢?
    QUEUESIZE = 4096<sizeof(T)? 1 : 4096/sizeof(T),如果单个元素的大小超过4K,那么二维数组只开辟1个元素位置,否则开辟4096/sizeof(T)个元素。(VC++6.0这样定义)
    在这里插入图片描述

  3. 一开始first和last放到二维数组的中间,原因还是因为它将来要头尾都要进出元素,所以不能放在头,也不能放在尾,不然总是要扩容,事实上这个二维数组还有空闲位置;

  4. 提供四个进出对接口,push_back、pop_front、push_back、pop_back,假设我们一致从头添加数据,知道第一个二维数组满时如下图,新增一个二维数组如下图;
    第一个二维数组满时:在这里插入图片描述
    新增一个二维数组:在这里插入图片描述

  5. 如果我继续push_front,直到新增的缓冲区(二维数组)都满了,会发生什么,此时没有可以继续申请的二维数组了,那就要增加一位数组的容量了,这里一维数组的容量是以二倍扩容,cnt*=2,pos = cnt/2-1,其中pos表示旧的二维数组将从pos这个位置开始挨个重新布置
    在这里插入图片描述

  6. 从尾部添加同理。deque每次增长完一维数组,都会调整二维数组的位置,保证二维数组的地址处于一维数组的中间,保证头尾都预留位置。

  7. deque提供了operator[]运算符重载重载函数,我们看到实际上deque是不连续的,能实现[],归功于deque强大的迭代器。

在这里插入图片描述
这张图是从网上找到的,对于初学者不必细究这张图,否则你可能会有点懵。

三、deque常用接口:

Defined in header <deque>
template<
    class T,
    class Allocator = std::allocator<T>
> class deque;

Member functions
(constructor)
 
constructs the deque 
(public member function)
(destructor)
 
destructs the deque 
(public member function)
operator=
 
assigns values to the container 
(public member function)
assign
 
assigns values to the container 
(public member function)
get_allocator
 
returns the associated allocator 
(public member function)
Element access
at
 
access specified element with bounds checking 
(public member function)
operator[]
 
access specified element 
(public member function)
front
 
access the first element 
(public member function)
back
 
access the last element 
(public member function)
Iterators
begin
cbegin
  
 
returns an iterator to the beginning 
(public member function)
end
cend
  
 
returns an iterator to the end 
(public member function)
rbegin
crbegin
  
 
returns a reverse iterator to the beginning 
(public member function)
rend
crend
  
 
returns a reverse iterator to the end 
(public member function)
Capacity
empty
 
checks whether the container is empty 
(public member function)
size
 
returns the number of elements 
(public member function)
max_size
 
returns the maximum possible number of elements 
(public member function)
shrink_to_fit
  
(C++11)
 
reduces memory usage by freeing unused memory 
(public member function)
Modifiers
clear
 
clears the contents 
(public member function)
insert
 
inserts elements 
(public member function)
emplace
  
(C++11)
 
constructs element in-place 
(public member function)
erase
 
erases elements 
(public member function)
push_back
 
adds an element to the end 
(public member function)
emplace_back
  
(C++11)
 
constructs an element in-place at the end 
(public member function)
pop_back
 
removes the last element 
(public member function)
push_front
 
inserts an element to the beginning 
(public member function)
emplace_front
  
(C++11)
 
constructs an element in-place at the beginning 
(public member function)
pop_front
 
removes the first element 
(public member function)
resize
 
changes the number of elements stored 
(public member function)
swap
 
swaps the contents 
(public member function)
Non-member functions
operator==
operator!=
operator<
operator<=
operator>
operator>=
 
lexicographically compares the values in the deque 
(function template)
std::swap(std::deque)
 
specializes the std::swap algorithm 
(function template)
erase(std::deque)
erase_if(std::deque)
  
(C++20)
 
Erases all elements satisfying specific criteria 
(function template)


deque扩容时,一维数组进行二倍扩容,二维数组是固定长度的。

四、参考链接:
https://en.cppreference.com/w/cpp/container/deque
https://en.cppreference.com/w/cpp/header/deque


版权声明:本文为KingOfMyHeart原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。