deque容器

deque容器

deque容器基本概念
vector容器是单向开口的连续内存空间,deque则是一种双向开口的连续性内存空间。所谓的双向开口,意思是可以在头尾两端分别做元素的插入和删除操作,当然,vector容器也可以在头尾两端插入元素,但是在其头部操作效率奇差,无法接受。
deque容器和vector容器的最大差异,一在于deque允许使用常数项时间对头端进行元素的插入和删除操作。二在于deque没有容量的概念,因为它是动态的以分段连续空间组合而成,随时可以增加一段新的空间并链接起来,换句话说,像vector那样,旧空间不足而重新配置一块更大的空间,然后复制元素,再释放旧空间,这样的事情在deque身上是不会发生的,也因此,deque没有必须要提供的空间保留(reserve)功能。
deque 容器中的元素是序列,但是内部的存储方式和 vector 不同。它组织元素的方式导致容器的大小总是和容量相等。因为这个,所以没有定义成员函数 capacity(),deque 只有成员函数 size(),它以成员类型 size_type 的无符号整型来返回当前元素个数。
虽然deque容器也提供了Random Access Iterator,但是它的迭代器并不是普通的指针,其复杂度和vector不是一个量级,这个当然影响各个运算的层面。因此,除非有必要,我们尽可能的使用vector,而不是deque,对deque进行的排序操作,为了最高效率,可将deque先完整的复制到一个vector中,对vector容器进行排序,再复制回deque。
deque容器实现原理
deque容器是连续的空间,至少逻辑上看来如此,连续线性空间总是令我们联想到array和vector,array无法成长,vector虽然可以成长,却只能向尾端成长,而且其成长其实是一个假象,事实上(1)申请更大空间(2)原数据复制新空间(3)释放原空间,三个步骤,如果不是vector每次配置新的空间时都留有余裕,其成长假象所带来的代价是非常昂贵的。
deque是有一段一段的定量的连续空间构成,一旦有必要在deque前端或者尾端增加新的空间,便配置一段连续定量的空间,串接在deque的头端或尾端,deque最大的工作就是维护这些分段连续的内存空间的整体性的假象,并提供随机存取的接口,避开了重新配置空间,复制,释放的轮回,代价就是复杂的迭代器构造。
既然deque是分段连续内存空间,那么久必须有中央控制,维持整体连续的假象,数据结构的设计及迭代器的前进后退操作颇为繁琐,deque代码的实现远比vector或list都多的多。
deque采取一块所谓的map(注意不是stl的map容器)作为主控,这里所谓的map是一小块连续的内存空间,其中每一个元素(此处成为一个结点)都是一个指针,指向另一端连续性内存空间,称作缓冲区,缓冲区才是deque的存储空间主题。

deque常用API

deque构造函数:
dequedeqT; //默认构造函数
deque(beg,end); //构造函数将(beg,end)区间中的元素拷贝给本身
deque(n,elem); //构造函数将n个elem拷贝给本身
deque(const deque& deq); //拷贝构造函数

deque赋值操作:
assign(beg,end) //将(beg,end)区间的数据拷贝赋值给本身
assign(n,elem) //将n个elem拷贝赋值给本身
deque &operator = (const deque & deq) //重载等号操作符
swap(deq) //将deq与本身的元素互换

deque大小操作:
deque.size(); //返回容器中元素的个数
deque.empty(); //判断容器是否为空
deque.resize(num); //重新指定容器的长度,若容器变长,则以默认值填充新的位置,如果容器变短,则末尾超出容器长度的元素被移除
deque.resize(num,elem) //重新指定容器的长度,若容器变长,则以elem填充新的位置,如果容器变短,则末尾超出容器长度的元素被移除

//An highlighted block
void printDeque(const deque<int> &d)
	{
	//iterator 普通迭代器    reverse_iterator 逆序迭代器    const_iterator 只读迭代器
	for(deque<int>::const_iterator it = d.begin();it != d.end();it++)
		{
			//*it= 100000;
			cout << *it << " " ;
		}
	cout << endl;
	}
void test1()
	{
		deque<int>d;
		d.push_back(10);
		d.push_back(20);
		d.push_back(30);
		d.push_back(40);
		printDeque(d);
	
		deque<int>d2(d.begin(),d.end());
		d2.push_back(1000);
		//交换
		d.swap(d2);
		printDeque(d);

		//d2 10,20,30,40
		if(d2.empty())
			{
				cout << "为空" << endl;
			}
		else
			{
			cout << "不为空,大小为:" << d2.size() << endl;
			}

	}

在这里插入图片描述

deque双端插入和删除操作
push_back(elem); //在容器尾部添加一个数据
push_front(elem); //在容器头部插入一个人数据
pop_back(); //删除容器最后一个数据
pop_front(); //删除容器第一个数据

deque数据存取:
at(index); //返回索引index所指向的数据,如果index越界,抛出out_of_range
operator[]; //返回索引index所指向的数据,如果index越界,不会抛出异常,直接挂掉
front(); //返回第一个数据
back(); //返回最后一个数据

deque插入操作:
insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置
insert(pos,n,elem); //在pos位置插入n个elem元素,无返回值
insert(pos,beg,end); //在pos位置插入(beg,end)区间的数据,无返回值

deque删除操作:
clear(); //移除容器的所有数据
erase(beg.end); //删除(beg,end)区间的数据,无返回值
erase(pos); //删除pos位置的数据,返回下一个数据的位置

//An highlighted block
void test2()
	{
		deque<int>d;
		d.push_back(10);
		d.push_back(20);
		d.push_back(30);
		d.push_front(40);
		d.push_front(50);
		printDeque(d);			//50 40 10 20 30 

		//删除 头删  尾删
		d.pop_back();
		d.pop_front();
		printDeque(d);

		cout << "front:"  << d.front() << endl;
		cout << "back:" << d.back() << endl;

		//插入
		deque<int>d2;
		d2.push_back(50);
		d2.push_back(60);
		d2.insert(d2.begin(),d.begin(),d.end());
		printDeque(d2);
	}

在这里插入图片描述

deque方法
deque c 创建一个空的deque
deque c1(c2) 复制一个deque。
deque c(n) 创建一个deque,含有n个数据,数据均已缺省构造产生。
deque c(n, elem) 创建一个含有n个elem拷贝的deque
deque c(beg,end) 创建一个以[beg;end)区间的deque
c.~deque() 销毁所有数据,释放内存

c.assign(beg,end) 将[beg; end)区间中的数据赋值给c。
c.assign(n,elem) 将n个elem的拷贝赋值给c。
c. at(idx) 传回索引idx所指的数据,如果idx越界,抛出out_of_range。
c.back() 返回容器c的最后一个元素的引用。如果c为空,则该操作未定义。
c.begin() 传回迭代器中的第一个数据地址。
c.clear() 移除容器中所有数据。
c.empty() 判断容器是否为空。
c.end() 返回一个迭代器,它指向容器c的最后一个元素的下一位置。
c.erase(pos) 删除pos位置的数据,传回下一个数据的位置。
c.erase(beg,end) 删除[beg,end)区间的数据,传回下一个数据的位置。
c.front() 返回容器c的第一个元素的引用。如果c为空,则该操作为空。
get_allocator 使用构造函数返回一个拷贝。
c.insert(pos,elem) 在pos位置插入一个elem拷贝,传回新数据位置
c.insert(pos,n,elem) 在pos位置插入>n个elem数据。无返回值
c.insert(pos,beg,end) 在pos位置插入在[beg,end)区间的数据。无返回值
c.max_size() 返回容器c可容纳的最多元素个数。
c.pop_back() 删除最后一个数据。
c.pop_front() 删除头部数据。
c.push_back(elem) 在尾部加入一个数据。
c.push_front(elem) 在头部插入一个数据。
c.rbegin() 返回一个逆序迭代器,它指向容器c的最后一个元素。
c.rend() 返回一个逆序迭代器,它指向容器c的第一个元素的前一个位置。
c.resize(num) 重新指定队列的长度。
c.size() 返回容器中实际数据的个数。
c.swap(c2) 交换容器c和c2中的所有元素。
swap(c1,c2) 交换容器c1和c2中的所有元素,和上一方法相似。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值