容器deque深入学习

来源:互联网 发布:淘宝信誉店铺出售 编辑:程序博客网 时间:2024/05/21 06:12

deque简介

    deque是双向开口的连续性存储空间。虽说是连续性存储空间,但这种连续性只是表面上的,实际上它的内存是动态分配的,它在堆上分配了一块一块的动态储存区,每一块动态存储去本身是连续的,deque自身的机制把这一块一块的存储区虚拟地连在一起。

    它首次插入一个元素,默认会动态分配512字节空间,当这512字节空间用完后,它会再动态分配自己另外的512字节空间,然后虚拟地连在一起。deque的这种设计使得它具有比vector复杂得多的架构、算法和迭代器设计。它的性能损失比之vector,是几个数量级的差别。所以说,deque要慎用。

deque数据结构

    deque是连续线性空间。但这种连续不同于数组和vector的连续,deque只是逻辑上的连续空间,它把一块一块独立的空间逻辑地连在一起,仿佛整个deque空间是一块完整的连续空间,让我们来看一下deque的数据结构,了解deque是怎么做到这一点的。


    我们发现这里有一个_Map成员变量。大家注意,这可不是STL中的map。这个_Map是一个指针,指向一块特殊的内存地址,这里保存着指向deque动态申请的所有512字节内存空间的首地址。deque先用一段小的连续空间顺序存放了一个一个指针,然后这些顺序存放的指针再各自指向用来真正存放数据的512字节连续性空间。当_Map指向的这块空间不够存放内存指针的时候,就会另觅一块更大的连续性空间,然后把指针一个一个复制过去,并销毁旧的空间。利用这种数据结构,deque就能方便地模拟自身的存储区是连续性空间的假象,并且可以实现双向插入删除的功能。deque没有vector所谓的容量的概念。我们看一下deque的数据结构图,如图1所示。


    deque通过一套复杂的机制实现了双向开口的连续性空间,增加了编程灵活性,但是也降低了效率。所以一定要慎用deque。

stack和queue

    用于STL中的stack和queue都是建立在deque数据结构基础上的,所以我们再来看看stack和queue。

 栈stack

    它是一种先进后出(First In Last Out)的数据结构。因为stack不允许对容器的遍历操作,所以stack没有迭代器。只能通过压栈和出栈的办法存取stack中的元素。

队列

    它是一种先进先出(First In First Out)的数据结构。因为queue不允许容器的遍历操作,所以queue没有迭代器,只能通过queue的最顶端和最低端操作数据。

deque的特点:

1、支持随机访问,即支持[]以及at(),但是性能没有vector好。

2、可以在内部进行插入和删除操作,但性能不及list。


deque与vector的对比

deque和vector的不同之处:

1、两端都能够快速插入和删除元素。vector只能在尾端进行。

2、deque的元素存取和迭代器操作会稍微慢一些。因为deque的内部结构会多一个间接过程。

3、迭代器是特殊的智能指针,而不是一般指针。它需要在不同的区块之间跳转。

4、deque可以包含更多的元素,其max_size可能更大。因为不止使用一块内存。

5、不支持对容量和内存分配时机的控制。

注意:在除了首尾两端的其他地方插入和删除元素,都将会导致指向deque元素的任何pointers、references、iterators失效。不过,deque的内存重分配优于vector。因为其内部结构显示不需要复制所有元素。

6、deque的内存区块不再被使用时,会被释放。deque的内存大小是可缩减的。不过,是不是这么做以及怎么做由实作版本定义。

 

deque和vector相似的特性:

1、在中间部分插入和删除元素相对较慢,因为所有元素都要被移动。

2、迭代器属于随即存取迭代器。

 

最好采用deque的情形:

1、需要在两端插入和删除元素。

2、无需引用容器内的元素。

3、要求容器释放不再使用的元素。

 

deque的操作函数

构造函数和析构函数:

 \

 

非变动性操作:

 \

 

变动性操作:

 \

 


deque的各项操作只有一下两点和vector不同:

deque不提供容量操作:capacity()和reverse()。

deque直接提供函数完成首尾元素的插入和删除。

其他均与vector相同。

注意:
   1、除了at()函数,其他成员函数都不会检查索引或迭代器是否有效。

2、元素的插入和删除可能会导致内存重新分配。所以任何插入或删除操作都会使所有指向deque元素的pointers、reference、iterators失效。唯一例外的是在首尾插入元素之后,pointers和reference可能仍然有效。

 


程序示例:


[cpp]
#include <iostream>  
#include <deque>  
#include <string>  
#include <algorithm>  
 
using namespace std; 
 
int main() 

    deque<string> strDeq; 
 
    strDeq.assign(4,string("CHINA")); 
    strDeq.push_back("first_string"); 
    strDeq.push_front("last_string"); 
 
    copy(strDeq.begin(),strDeq.end(), 
        ostream_iterator<string>(cout," ")); 
    cout << endl; 
    cout << endl; 
 
    for(int i = 0;i < strDeq.size();++i) 
        cout << "strDeq[" << i << "] : " << strDeq[i] << endl; 
    cout << endl; 
     
    for(int i = 0;i < strDeq.size();++i) 
        cout << "strDeq.at(" << i << ") : " << strDeq.at(i) << endl; 
    cout << endl; 
 
    strDeq.pop_front(); 
    strDeq.pop_back(); 
 
    copy(strDeq.begin(),strDeq.end(), 
        ostream_iterator<string>(cout," ")); 
    cout << endl; 
    cout << endl; 
 
    for(int i = 1;i < strDeq.size();++i) 
        strDeq[i] = "pre" + strDeq[i]; 
    copy(strDeq.begin(),strDeq.end(), 
        ostream_iterator<string>(cout," ")); 
    cout << endl; 
    cout << endl; 
 
    strDeq.resize(4,"resized string"); 
 
    copy(strDeq.begin(),strDeq.end(), 
        ostream_iterator<string>(cout," ")); 
    cout << endl; 
    cout << endl; 

#include <iostream>
#include <deque>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
 deque<string> strDeq;

 strDeq.assign(4,string("CHINA"));
 strDeq.push_back("first_string");
 strDeq.push_front("last_string");

 copy(strDeq.begin(),strDeq.end(),
  ostream_iterator<string>(cout," "));
 cout << endl;
 cout << endl;

 for(int i = 0;i < strDeq.size();++i)
  cout << "strDeq[" << i << "] : " << strDeq[i] << endl;
 cout << endl;
 
 for(int i = 0;i < strDeq.size();++i)
  cout << "strDeq.at(" << i << ") : " << strDeq.at(i) << endl;
 cout << endl;

 strDeq.pop_front();
 strDeq.pop_back();

 copy(strDeq.begin(),strDeq.end(),
  ostream_iterator<string>(cout," "));
 cout << endl;
 cout << endl;

 for(int i = 1;i < strDeq.size();++i)
  strDeq[i] = "pre" + strDeq[i];
 copy(strDeq.begin(),strDeq.end(),
  ostream_iterator<string>(cout," "));
 cout << endl;
 cout << endl;

 strDeq.resize(4,"resized string");

 copy(strDeq.begin(),strDeq.end(),
  ostream_iterator<string>(cout," "));
 cout << endl;
 cout << endl;
}

运行结果:\

参考链接:

             

0 0
原创粉丝点击