您的位置:首页 > 产品设计 > UI/UE

STL之deque

2014-01-15 23:45 148 查看

deque简介

        deque是双向开口的连续性存储空间。虽说是连续性存储空间,但这种连续性只是表面上的,实际上它的内存是动态分配的,它在堆上分配了一块一块的动态储存区,每一块动态存储去本身是连续的,deque自身的机制把这一块一块的存储区虚拟地连在一起。        它首次插入一个元素,默认会动态分配512字节空间,当这512字节空间用完后,它会再动态分配自己另外的512字节空间,然后虚拟地连在一起。deque的这种设计使得它具有比vector复杂得多的架构、算法和迭代器设计。它的性能损失比之vector,是几个数量级的差别。所以说,deque要慎用。除非你要经常执行双端的插入和删除在这里说下它和vector的区别,vector众所周知了,内存中是一个动态数组,根据元素个数动态的申请内容空间,不适合大量做删除和插入操作,deque就这点和vector很像,我们可以从MSDN中查到deque的api比vector只多了两个方法push_front()和pop_front()方法,其他都一样,因此除非我们经常要在双端做插入和删除,否则我们已定要用vector,因为vector也支持push_back()和pop_back(),而且效率要比deque效率高的多。下面解释具体原因(当然要从deque实现的数据结构讲起喽)

deque数据结构

        我们想要实现高效的数据存取自然想用数组(连续的存储空间而不是链表),可是动态数组又有很大的局限性,因为一旦内存申请完毕,则该段内存的起始位置是固定的,我们不容易做到在这个连续空间的基础上实现双端的插入和删除(意味着数据的大量移动,尤其是在前端插入数据,这也正式vector不支持push_front()和pop_front()的原因),那deque是如何做到的呢(用连续的空间实现双端操作)?deque是连续线性空间,但这种连续不同于数组和vector的连续,deque只是逻辑上的连续空间,它把一块一块独立的空间逻辑地连在一起,仿佛整个deque空间是一块完整的连续空间,让我们来看一下deque的数据结构,了解deque是怎么做到这一点的。
template<<SPAN style="COLOR: rgb(0,0,255); LINE-HEIGHT: 21px">class _Ty, class _A= allocator<_Ty> >
class deque
{
...
protected:
iterator _First, _Last;
_Mapptr _Map;
 

size_type _Mapsize, _Size;
};
我们发现这里有一个_Map成员变量。大家注意,这可不是STL中的map。这个_Map是一个指针,指向一块特殊的内存地址,这里保存着指向deque动态申请的所有512字节内存空间的首地址。deque先用一段小的连续空间顺序存放了一个一个指针,然后这些顺序存放的指针再各自指向用来真正存放数据的512字节连续性空间。当_Map指向的这块空间不够存放内存指针的时候,就会另觅一块更大的连续性空间,然后把指针一个一个复制过去,并销毁旧的空间。利用这种数据结构,deque就能方便地模拟自身的存储区是连续性空间的假象,并且可以实现双向插入删除的功能。deque没有vector所谓的容量的概念。我们看一下deque的数据结构图,如图1所示。        deque通过一套复杂的机制实现了双向开口的连续性空间,增加了编程灵活性,但是也降低了效率。通常它的插入和删除效率要比vector慢几个数量级,所以一定要慎用deque。

stack和queue

        谈完了deque,我们免不了要提一提STL中的stack和queue,它们都是建立在deque数据结构基础上的。  以下摘自MSDN:     
	template<class T,class Cont = deque<T> >class stack {public:typedef Cont::allocator_type allocator_type;typedef Cont::value_type value_type;typedef Cont::size_type size_type;explicit stack(const allocator_type& al = allocator_type()) const;bool empty() const;size_type size() const;allocator_type get_allocator() const;value_type& top();const value_type& top() const;void push(const value_type& x);void pop();protected:Cont c;};
我们看到stack模板中它的一个成员是Cont类型,而Cont类型定义为class Cont = deque<T>,所以stack的默认实现是deque,
同理queue也是一样。当系统效率要求较高时,我们童谣要要慎用STL中的这两种数据结构。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息