STL中常用的容器——deque容器

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

4.Deque常用的API
4.1deque 构造函数

deque<T> deqT;//默认构造形式
deque(beg, end);//构造函数将[beg, end)区间中的元素拷贝给本身。
deque(n, elem);//构造函数将 n 个 elem 拷贝给本身。
deque(const deque &deq);//拷贝构造函数。

4.2deque 赋值操作

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

4.3deque 大小操作

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

4.4deque 双端插入和删除操作

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

4.5deque 数据存取

at(idx);//返回索引 idx 所指的数据,如果 idx 越界,抛出 out_of_range。 
operator[];//返回索引 idx 所指的数据,如果 idx 越界,不抛出异常,直接出错。 front();//返回第一个数据。 
back();//返回最后一个数据

4.6deque 插入操作

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

4.7deque 删除操作

clear();//移除容器的所有数据 
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除 pos 位置的数据,返回下一个数据的位置。

注:上述API使用举例和vector使用十分相似,请参考
vector容器
5.vector容器和Deque容器举例
案例描述:
写一个简单的裁判评分系统,输入十个成绩,去掉最高和最低,取平均分

class Person
{
public:
	Person(string name)
	{
		this->name = name;
	}
	string name;
	float score;
};

void test02()
{
	vector<Person> v;
	deque<int> d;
	int temp = 0;
	int sum = 0;
	deque<int>::iterator begin;
	deque<int>::iterator end;

	Person p1("李白");
	Person p2("项羽");
	Person p3("韩信");
	Person p4("猴子");
	Person p5("诸葛");

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);

	vector<Person>::iterator it_begin = v.begin();
	vector<Person>::iterator it_end = v.end();
	
	for (; it_begin != it_end; it_begin++)
	{
		
		for (int i = 0; i < 10; i++)
		{
			cout << "请输入裁判" << i + 1 << "对" << it_begin->name << "的评分:";
			/*获取输入数据*/
			cin >> temp;
			d.push_back(temp);
		}
		cout << "取最大和最小算出平均分..." << endl;
		/*排序的时候最好使用一个vector容器,将Deque容器的东西复制到vector容器
		可以提高效率*/
		sort(d.begin(), d.end());
		d.pop_back();
		d.pop_front();
		/*获取迭代器*/
		begin = d.begin();
		end = d.end();
		/*遍历Deque容器*/
		for (; begin != end; begin++)
		{
			sum += *begin;
		}
		it_begin->score = sum / d.size();
		cout << "计算出选手"<< it_begin->name << "的成绩:" << it_begin->score << endl;
	}

}

执行效果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值