STL常用容器解析

STL容器

stl提供了大量成熟的容器供我们存储数据,在连接各自容器的特点的情况下,选择性的使用最合适的容器,会使代码质量与性能大大提升,下面记录下各自常用容器的特性:

1. std::vector

vector是一种非常常用的数组类型的容器,使用非常方便,但在某些场景下,其数据结构并不能带来良好的性能优势。
在这里插入图片描述

2. rb_tree(红黑树)

这里不过深的探究红黑树的数据结构及其旋转树形逻辑,主要是因为stl中常用的容器如map,set,内部都是封装的rb_tree来实现其功能的,所以有必要提前了解一下红黑树的一些规则及简单使用。
在这里插入图片描述

3. set/multiset

set/multiset相当于红黑树的一种容器适配器(container adapter),因为其底层封装了一个红黑树对象,其所有的操作都是由该对象来完成的
在这里插入图片描述

#include <set>
#include <stdlib.h> // rand()
#include <time.h>
void TestSet()
{
	std::set<int> mySet = {1, 5,2,8,4};
	for (const auto& i : mySet) {
		std::cout << i << " ";
	}// 1 2 4 5 8
	mySet.insert(5); // b不报错,但也不会插入

	std::multiset<int> myMultiSet = { 1, 5,2,8,4 };
	for (const auto& i : mySet) {
		std::cout << i << " ";
	}// 1 2 4 5 8
	myMultiSet.insert(5);// 1 2 4 5 5 8
	std::cout << std::endl;
	auto itr = myMultiSet.begin();
	std::cout << *itr;
	// *itr = 2;   // 编译不通过

	// 测试集合的搜索效率
	// 插入100,0000个随机元素,可能会存在重复值
	std::multiset<int> bigSet;
	// int 4个字节 取值范围 -2147483648~2147483647[-2^31~2^31-1]
	// rand()  返回值范围0~32767
	clock_t start, end;
	start = clock();
	int length = 1000000;
	for (int i = 0; i < length; ++i) {
		bigSet.insert(rand());

	}
	end = clock();
	std::cout << "insert element cost time: " << double(end - start) << "个CPU时钟单元";//14502

	int findVal = 3456;

	// 用std::find算法查找
	start = clock();
	auto res = std::find(bigSet.begin(), bigSet.end(), findVal);
	end = clock();
	std::cout << "std::find cost time: " << double(end - start) << "个CPU时钟单元";//27
	if (res != bigSet.end()) {
		std::cout << "Find;";
	}
	else {
		std::cout << "Not Find;";
	}

	//用集合自带的find接口查找
	start = clock();
	res = bigSet.find(findVal);
	end = clock();
	std::cout << "set.find cost time: " << double(end - start) << "个CPU时钟单元";//0
	if (res != bigSet.end()) {
		std::cout << "Find;";
	}
	else {
		std::cout << "Not Find;";
	}
	
}

4. map/multimap

map/mmultimap也相当于红黑树的一种容器适配器(container adapter),因为其底层封装了一个红黑树对象,其所有的操作都是由该对象来完成的,与set/multiset的区别在于key与value不同,需要传入key和data两个值
在这里插入图片描述

#include <map>
void TestMap()
{
	std::map<int, std::string> myMap = { {1, "a"}, {5, "e"}, {3, "c"},{9,"d"} };
	for (const auto& iEle : myMap) {
		std::cout << iEle.first<< " ";
	}// 1 3 5 9
	myMap.insert(std::pair<int, std::string>(5, "g")); // b不报错,但也不会插入
	myMap[15] = "dfd";
	myMap[1] = "op";

	std::multimap<int, std::string> myMultiMap = { {1, "a"}, {5, "e"}, {3, "c"},{9,"d"} };
	for (const auto& iEle : myMultiMap) {
		std::cout << iEle.first << " ";
	}// 1 2 4 5 8
	myMultiMap.insert(std::pair<int, std::string>(5, "g"));// 1 2 4 5 5 8
	std::cout << std::endl;
	auto itr = myMultiMap.begin();
	itr->second = "gh";
	// myMultiMap[1] = "787"; // 编译报错

}

5. std::list

list是一种环状的双向链表,其插入和删除元素比较高效
在这里插入图片描述

6. std::deque/queue/stack

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/tianzhiyi1989sq/article/details/105310531