C++ std::deque (tcy)

1.1.特点:
    在头尾安插元素十分迅速。 在中间安插元素比较费时因为必须移动其它元素
    
1.2.说明:
    双端队列是一个索引序列容器,允许在首尾快速插入和删除。
    在双端队列两端插入和删除绝不会使指向其余元素的指针或引用无效。

    双端队列元素不是连续存储:
        典型实现使用一系列单独分配固定大小数组,并带有额外簿记,
        与矢量相比对双端队列索引访问必须执行两个指针取消引用索引访问仅执行一次。

    双端队列存储会根据需要自动扩展和收缩。
    扩展双端队列比扩展std :: vector便宜,不涉及将现有元素复制到新的内存位置。
    双端队列通常具有很大最小存储成本。仅包含一个元素的双端队列必须分配其完整的内部数组

1.3.函数: 

函数 说明
(构造函数) 构造deque
(destructor) 破坏deque
operator= 为容器分配值
get_allocator() 返回关联的分配器
void assign(init_list={})   为容器重新分配数据-清除原数据(initialize_list)
void assign(int nSize, const T& v) 重新分配n个重复值v
void assign(iter begin, iter end) 重新分配[begin,end)个数据
Capacity容量  
bool empty() 检查容器是否为空
size_t size() 返回元素数
size_t max_size() 返回最大可能的元素数
void shrink_to_fit() 通过释放未使用的内存来减少内存使用
Element access元素访问  
T at(size_t pos) 读写元素pos-边界检查
T operator[] 读写元素pos-无边界检查
T front() 读写首元素
T back() 读写尾元素
操作:  
void push_front(const T & x) 在开始处插入一个元素
void push_back(const T & x) 在末尾添加一个元素
iter insert(iterator it, const T & x) 插入元素x
iter insert(iterator it, int n, const T & x); 插入n个元素x
iter insert(iterator it, iterator first, iterator last) 插入另一个向量的[forst, last] 间的数据
void clear() 清空所有元素
void pop_front() 删除第一个元素
void pop_back() 删除最后一个元素
iter erase(iterator it) 删除iter处元素
iter erase(iterator first, iterator last) 删除指定范围元素
Iterators迭代器  
begin/cbegin/rbegin/crbegin 将迭代器返回到开头
end/cend/rend/crend 将迭代器返回到末尾
Modifiers修饰符  
emplace 就地构造元素
emplace_back 在末尾就位构造一个元素
emplace_front 在开始处就位构造一个元素
resize 更改存储的元素数
swap 交换内容
Non-member functions  
std::swap(std::deque) 专门研究std :: swap算法C++20)
erase_if(std::deque) 擦除所有满足特定条件的元素C++20)
迭代器无效:
    1)swap, std::swap 过去的迭代器可能无效(定义实现) 
    2)rinke_to_fit,clear,insert,emplace,push_front,push_back,emplace_front,emplace_back 总是无效 
    3)erase 如开始擦除-仅擦除元素;如在最后擦除-仅擦除元素和过去的迭代器, 
          否则-所有迭代器均无效(包括过去的迭代器)
    4)resize如果新大小小于旧大小:仅删除元素和过去的迭代器 
          如果新的大小大于旧的大小:所有迭代器均无效,否则-所有迭代器均无效。 
    5)pop_front 仅删除元素 
    6)pop_back 仅删除元素和过去的迭代器 

失效说明:  
    1)在双端队列的任一端插入时,insert和emplace不会使引用无效  
    2)push_front,push_back,emplace_front和emplace_back不会使对双端队列元素的任何引用无效  
    3)当在双端队列的两端擦除时,对未擦除元素的引用不会被delete,pop_front和pop_back无效。  
    4)调用较小的调整大小不会使对未擦除元素的任何引用无效。  
    5)要在通话调整大小以更大的尺寸不坏的双端队列的元素的任何引用。
2.实例:
    #include <iostream>
    #include <deque>
    #include<assert.h>
    #include <algorithm>

    using namespace std;

    #define print(s)                \
    {                               \
        cout << "(";                \
        for (auto v : s)            \
           {cout << v <<","; }      \
        cout << ")" << endl;        \
    }

    template<typename T>
    size_t DEQUE_MAX_SIZE(){return static_cast<size_t>(-1) / sizeof(T);}
   
int main(){

        //1.1.定义及初始化
        deque<int> d{1,2,3,4};
        deque<int> d1;             // 定义双端队列
        deque<int> d2(4);          // 定义双端队列初始大小为4
        deque<int> d3(4, 1);       // 定义端队列,初始大小4初始值都为1
        deque<int> d4(d);          // 定义并用双端队列a初始化双端队列b
        deque<int> d5(d.begin(), d.begin() + 3); // d5=d[0,3)(共3个)

        
        int arr[] = { 1, 2, 3, 4, 5 };
        deque<int> d6(arr, arr + 5);     // 将数组前5个元素作为双端队列初值
        deque<int> d7(&arr[1], &arr[4]); // 将arr[1,3]作为双端队列初值

        //1.2.重新分配元素清除原数据:
        d.assign({ 11,12,13 });          //(11, 12, 13, )
        d.assign(3, -1);                 //(-1, -1, -1, )
        d.assign(d6.end() - 4, d6.end());//(2, 3, 4, 5, )
        
        //2.容量函数
        assert(d.size() == 4);                        //容器大小
        assert(d.empty() == false);
        assert(d.max_size() == DEQUE_MAX_SIZE<int>());//最大容量
        
        d.resize(6);                                  //更改容器大小
        assert(d.size() == 6);
        
        d.shrink_to_fit();     //减少容器大小到满足元素所占存储空间的大小
        assert(d.size() == 6);
        

        //3. 元素访问-读写
        assert(d.front() == d[0]);       //d[0]边界不检查
        assert(*d.begin() == d.at(0));   //d.at(0)边界检查
        assert(d.back() == d[d.size() - 1]);
        assert(d.back() == *(d.end() - 1));

        //4.添加元素:
        d.resize(2);//(2,3,)
        d.push_front(1);                // 头部增加元素1   (1, 2, 3 )
        d.push_back(4);                 // 末尾添加元素(1, 2, 3, 4,)
        
        d.insert(d.begin()+1, -23);     //位置2插入元素-23 (1,-23,2,3,4,)
        d.insert(d.end(), 2,-1);        //任意位置插入n个相同元素(1,-23,2,3,4,-1,-1,)
        
        // 插入另一个向量的[forst,last]间的数据
        d.insert(d.end(), d7.begin()+1, d7.end());//(1,-23,2,3,4,-1,-1,3,4,)
  
        //5.删除函数	
        d.pop_front();                    // 头部删除元素
        d.pop_back();                     // 末尾删除元素
                
        d.erase(d.begin()+1);             // 任意位置删除一个元素
        d.erase(d.begin(), d.begin() + 1);// 删除[first,last]之间的元素
        d.clear();// 清空所有元素

        //6.迭代遍历
        d.emplace(d.begin(), 1);
        d.insert(d.end(), { 2,3 });
        reverse(d.begin(), d.end());//元素翻转
        cout << *(d.begin() + 1) << endl;

        sort(d.begin(), d.end()); // 元素排序:小到大的排序

        auto Comp = [&](const int& a, const int& b)->bool {return a > b; };
        sort(d.begin(), d.end(), Comp);//自定义排序
        print(d);
        
        // 遍历显示
        for (deque<int>::iterator it = d.begin(); it != d.end(); it++)
            cout << *it << endl;    
    }

 

 

 

 

 

 

 

 

上一篇:[转载]C++ STL 双端队列deque详解


下一篇:java中LinkedList.push的陷阱