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是一种环状的双向链表,其插入和删除元素比较高效