栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C++】STL容器

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C++】STL容器

序列式容器 deque

deque容器是双端队列,支持快速随机访问,在头尾位置插入/删除元素速度很快。

  • vector容器对于在头部的插入、删除效率低,且数据量越大,效率越低。相对而言,deque容器对于在头部的插入、删除速度比vector容器快
  • vector容器访问元素的速度比deque容器快
  • deque容器的内存重分配优于vector容器,因为其内部结构不需要复制所有元素

deque容器内部有一个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据。中控器维护的是每个缓冲区的地址,使得使用deque容器时像是一片连续的内存空间。

list

STL中的list容器是一个双向循环链表,只支持双向顺序访问,在list容器中任何位置插入/删除速度很快。

  • 链表中的迭代器只支持前移和后移
  • 插入/删除操作不会造成原有的迭代器失效

所有不支持随机访问迭代器的容器, 不可以用标准算法, 但内部会提供对应一些算法!

#include 
#include 
using namespace std;

void printList(const list& L)
{
	for (list::const_iterator it = L.begin(); it != L.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

int main()
{
	list L;
	L.push_back(90);
	L.push_back(30);
	L.push_back(20);
	L.push_back(70);
	printList(L);	// 90 30 20 70

	// 反转
	L.reverse();
	printList(L);	// 70 20 30 90

	// 排序,默认升序
	L.sort();
	printList(L);	// 20 30 70 90

	// 排序,降序排序
	L.sort([](const int& num1, const int& num2) {return num1 > num2; });
	printList(L);	// 90 70 30 20
	system("pause");
	return 0;
}

什么情况下用vector,什么情况下用list,什么情况下用deque?

  • vector支持快速随机访问,但在非尾部插入/删除数据时效率很低,适合对象简单,对象数量变化不大,随机访问频繁的情况
  • 需要从首尾两端进行插入/删除操作的时候可以选择deque
  • 除非必要,我们尽可能选择使用vector而非deque,因为deque的迭代器比vector迭代器复杂很多
  • list不支持随机访问,适用于对象大,对象数量变化频繁,插入和删除频繁的情况。
配接器 stack

栈是一种先进后出的数据结构,栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为。

#include 
#include 
using namespace std;

int main()
{
	stack s;
	// 入栈
	s.push(10);
	s.push(20);
	s.push(30);

	// 栈是否为空
	while (!s.empty())
	{
		// 返回栈顶元素
		cout << "栈顶元素为: " << s.top() << endl;
		// 出栈
		s.pop();
	}
	// 返回栈的大小
	cout << "栈的大小为:" << s.size() << endl;
	system("pause");
	return 0;
}
queue

队列是一种先进先出的数据结构,队列允许从一端新增元素,从另一端移除元素,队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为。

#include 
#include 
#include 
using namespace std;

class Person
{
	friend ostream& operator<<(ostream& out, const Person& p);
public:
	Person(string name, int age) {
		this->m_Name = name;
		this->m_Age = age;
	}
private:
	string m_Name;
	int m_Age;
};

ostream& operator<<(ostream& out, const Person& p)
{
	out << "姓名:" << p.m_Name << " 年龄:" << p.m_Age;
	return out;
}

int main()
{
	queue q;

	Person p1("唐僧", 30);
	Person p2("孙悟空", 1000);
	Person p3("猪八戒", 900);
	Person p4("沙僧", 800);

	// 入队
	q.push(p1);
	q.push(p2);
	q.push(p3);
	q.push(p4);

	// 队列是否为空
	while (!q.empty())
	{
		// 返回队头元素
		cout << q.front() << endl;
		// 返回队尾元素
		cout << q.back() << endl;
		// 出队
		q.pop();
	}

	// 返回队列大小
	cout << "队列大小为: " << q.size() << endl;
	system("pause");
	return 0;
}
关联式容器 set / multiset
  • set/multiset属于关联式容器,底层结构是用红黑树实现
  • 所有元素在插入时自动按升序排序
  • set不允许容器中有重复的元素,multiset允许容器中有重复的元素
  • 对于自定义数据类型,set容器必须指定排序规则
// 基本使用
#include 
#include 
using namespace std;

void printSet(set& s)
{
	for (set::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

int main()
{
	set s;

	// 插入
	s.insert(10);
	s.insert(30);
	s.insert(20);
	s.insert(40);
	s.insert(50);
	s.insert(60);

	// 容器是否为空
	if (s.empty()) {
		cout << "set为空" << endl;
	}
	else {
		// 返回容器中元素的数目
		cout << "set的大小为: " << s.size() << endl;	// 6
	}

	// 删除
	s.erase(s.begin());
	printSet(s);	// 20 30 40 50 60

	s.erase(60);
	printSet(s);	// 20 30 40 50

	// 查找
	set::iterator pos = s.find(30);

	// 统计
	// 对于set容器来说,结果为0或1
	int num = s.count(30);
	cout << "num = " << num << endl;	// 1

	system("pause");
	return 0;
}
// set不允许容器中有重复的元素,multiset允许容器中有重复的元素
#include 
#include 
using namespace std;

int main()
{
	// set不允许插入重复值
	// set插入数据的同时会返回插入结果
	set s;
	pair::iterator, bool> ret = s.insert(10);
	if (ret.second) {
		cout << "第一次插入成功!" << endl;	// √
	}
	else {
		cout << "第一次插入失败!" << endl;
	}

	ret = s.insert(10);
	if (ret.second) {
		cout << "第二次插入成功!" << endl;
	}
	else {
		cout << "第二次插入失败!" << endl;	// √
	}

	// multiset允许插入重复的值
	multiset ms;
	ms.insert(10);
	ms.insert(10);

	for (multiset::iterator it = ms.begin(); it != ms.end(); it++) {
		cout << *it << " ";		// 10 10
	}
	cout << endl;

	system("pause");
	return 0;
}
// 所有元素在插入时自动按升序排序
#include 
#include 
using namespace std;

class MyCompare
{
public:
	bool operator()(int v1, int v2) const {
		return v1 > v2;
	}
};

int main()
{
	set s1;
	s1.insert(10);
	s1.insert(40);
	s1.insert(20);
	s1.insert(30);
	s1.insert(50);

	// set容器默认升序排序
	for (auto v : s1)
		cout << v << " ";
	cout << endl;	// 10 20 30 40 50

	// 指定降序排序
	set s2;
	s2.insert(10);
	s2.insert(40);
	s2.insert(20);
	s2.insert(30);
	s2.insert(50);

	for (auto v : s1)
		cout << v << " ";
	cout << endl;
	system("pause");
	return 0;
}
// 对于自定义数据类型,set容器必须指定排序规则
#include 
#include 
using namespace std;

class Person
{
	friend ostream& operator<<(ostream& out, const Person& p);
	friend class ComparePerson;
public:
	Person(string name, int age) {
		this->m_Name = name;
		this->m_Age = age;
	}
private:
	string m_Name;
	int m_Age;
};

ostream& operator<<(ostream& out, const Person& p) {
	out << "姓名: " << p.m_Name << " 年龄: " << p.m_Age;
	return out;
}

class ComparePerson
{
public:
	// 按照年龄降序排序 
	bool operator()(const Person& p1, const Person& p2) const {
		return p1.m_Age > p2.m_Age;
	}
};

int main()
{
	// 对于自定义数据类型,必须指定排序规则
	set s;

	Person p1("刘备", 30);
	Person p2("关羽", 27);
	Person p3("张飞", 24);
	Person p4("赵云", 21);
	s.insert(p1);
	s.insert(p2);
	s.insert(p3);
	s.insert(p4);

	for (auto p : s)
		cout << p << endl;
	system("pause");
	return 0;
}
map / multimap
  • map / multimap属于关联式容器,底层结构是用红黑树实现
  • map中所有元素都是pair,第一个元素为键值,起到索引作用,第二个元素为实际值
  • 所有元素都会根据元素的键值自动按升序排序
  • map不允许容器中有重复键值元素,multimap允许容器中有重复键值元素
  • 对于自定义数据类型,map容器必须指定排序规则
// 基本使用
#include 
#include 
using namespace std;

int main()
{
	map m;
	// 插入
	m.insert(pair(1, 10));
	m.insert(make_pair(2, 20));
	m.insert(map::value_type(3, 30));
	// 不建议使用[]插入
	m[4] = 40;

	// 如果没有这个键,就创建这个键值对,值为0
	m[5];
	for (const auto& p : m)
		cout << p.first << " " << p.second << " ";	// 1 10 2 20 3 30 4 40 5 0
	// 可以用于访问
	cout << m[1] << endl;	// 10

	// 删除
	m.erase(m.begin());		// 2 20 3 30 4 40 5 0
	m.erase(5);				// 2 20 3 30 4 40

	// 容器是否为空
	if (m.empty()) {
		cout << "map为空" << endl;
	}
	else {
		// 返回容器中元素的数目
		cout << "map的大小为: " << m.size() << endl;
	}

	// 按键查找
	map::iterator pos = m.find(3);

	// 按键统计
	// 对于map,结果为0或者1
	int num = m.count(3);
	cout << "num = " << num << endl;	// 1

	system("pause");
	return 0;
}
// 更改排序方式
#include 
#include 
using namespace std;

class MyCompare {
public:
	bool operator()(int v1, int v2) const {
		return v1 > v2;
	}
};

int main()
{
	map m;
	m.insert(make_pair(1, 10));
	m.insert(make_pair(2, 20));
	m.insert(make_pair(3, 30));
	m.insert(make_pair(4, 40));
	m.insert(make_pair(5, 50));

	for (map::iterator it = m.begin(); it != m.end(); it++) {
		cout << "key = " << it->first << " value = " << it->second << endl;
	}
	system("pause");
	return 0;
}

参考:https://www.bilibili.com/video/BV1et411b73Z

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/849241.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号