c++模板库容器list vector map set操作和性能对比

文章目录

list

列表(list)是C++ STL中的一种容器类型,它是一个双向链表,可以在任意位置高效地添加、删除、移动元素。

以下是一些常用的列表操作:

  1. 创建列表
c++ 复制代码
#include <list>
std::list<int> myList;
  1. 添加元素
c++ 复制代码
myList.push_back(1); // 在列表尾部添加元素
myList.push_front(2); // 在列表头部添加元素
myList.insert(myList.begin(), 3); // 在指定位置插入元素
  1. 删除元素
c++ 复制代码
myList.pop_back(); // 删除尾部元素
myList.pop_front(); // 删除头部元素
myList.erase(myList.begin()); // 删除指定位置的元素
  1. 遍历列表
c++ 复制代码
std::list<int>::iterator it;
for(it=myList.begin(); it!=myList.end(); ++it) {
    std::cout << *it << ' ';
}
  1. 获取列表大小
c++ 复制代码
std::cout << myList.size() << std::endl;
  1. 判断列表是否为空
c++ 复制代码
if(myList.empty()) {
    std::cout << "List is empty" << std::endl;
}
  1. 清空列表
c++ 复制代码
myList.clear();
  1. 列表排序
c++ 复制代码
myList.sort(); // 默认从小到大排序
myList.sort(std::greater<int>()); // 从大到小排序
  1. 反转列表
c++ 复制代码
myList.reverse();

以上是一些常用的列表操作,更多操作可以参考C++ STL中list的文档。

vector

C++中的vector是STL(标准模板库)中的容器之一,用于存储动态大小的元素序列。

以下是vector的常见操作:

  1. 创建一个空的vector:
c++ 复制代码
   vector<int> vec; // 创建一个空的vector<int>
   vector<string> strVec; // 创建一个空的vector<string>
  1. 在vector末尾添加元素:
c++ 复制代码
   vec.push_back(1); // 在vector末尾添加一个int类型元素1
   strVec.push_back("hello"); // 在vector末尾添加一个string类型元素"hello"
  1. 访问vector中的元素:
c++ 复制代码
   int firstElem = vec[0]; // 访问第一个元素
   string lastElem = strVec.back(); // 访问最后一个元素
  1. 获取vector的大小:
c++ 复制代码
   int size = vec.size(); // 获取vector中元素的个数
   bool isEmpty = strVec.empty(); // 判断vector是否为空
  1. 删除vector中的元素:
c++ 复制代码
   vec.pop_back(); // 删除vector末尾的一个元素
   strVec.erase(strVec.begin() + 2); // 删除vector中索引为2的元素
  1. 清空vector中所有元素:
c++ 复制代码
   vec.clear(); // 清空vector中所有元素
   strVec.resize(0); // 将vector的大小设置为0
  1. 遍历vector中的所有元素:
c++ 复制代码
   for (int i = 0; i < vec.size(); i++) {
       cout << vec[i] << " ";
   }
   
   for (auto s : strVec) {
       cout << s << " ";
   }

第二种方法可以使用C++11中的range-based for循环。

map

C++中的map是STL(标准模板库)中的关联容器之一,用于存储键值对。

以下是map的常见操作:

  1. 创建一个空的map:
c++ 复制代码
   map<string, int> myMap; // 创建一个空的map,键为string类型,值为int类型
  1. 在map中插入键值对:
c++ 复制代码
   myMap.insert(make_pair("apple", 10)); // 在map中插入键为"apple",值为10的键值对
   myMap["banana"] = 20; // 在map中插入键为"banana",值为20的键值对
  1. 访问map中的元素或查找键:
c++ 复制代码
   int value = myMap["apple"]; // 访问键为"apple"的值
   auto it = myMap.find("banana"); // 查找键为"banana"的迭代器
   if (it != myMap.end()) {
       int value = it->second; // 获取迭代器指向的值
   }
  1. 获取map的大小:
c++ 复制代码
   int size = myMap.size(); // 获取map中键值对的个数
   bool isEmpty = myMap.empty(); // 判断map是否为空
  1. 删除map中的键值对:
c++ 复制代码
   myMap.erase("apple"); // 删除键为"apple"的键值对
   auto it = myMap.find("banana");
   if (it != myMap.end()) {
       myMap.erase(it); // 删除迭代器指向的键值对
   }
  1. 清空map中的所有键值对:
c++ 复制代码
   myMap.clear(); // 清空map中的所有键值对
  1. 遍历map中的所有键值对:
c++ 复制代码
   for (auto it = myMap.begin(); it != myMap.end(); it++) {
       cout << it->first << ": " << it->second << endl;
   }
   
   for (auto elem : myMap) {
       cout << elem.first << ": " << elem.second << endl;
   }

第二种方法可以使用C++11中的range-based for循环。

set

C++中的set是STL(标准模板库)中的关联容器之一,用于存储不重复的元素,并按照一定顺序进行排序。

以下是set的常见操作:

  1. 创建一个空的set:
c++ 复制代码
   set<int> mySet; // 创建一个空的set,元素为int类型
  1. 在set中插入元素:
c++ 复制代码
   mySet.insert(10); // 在set中插入元素10
   mySet.insert(20); // 在set中插入元素20
   mySet.insert(30); // 在set中插入元素30
  1. 访问set中的元素或查找元素:
c++ 复制代码
   auto it = mySet.find(20); // 查找元素20的迭代器
   if (it != mySet.end()) {
       int value = *it; // 获取迭代器指向的值
   }
  1. 获取set的大小:
c++ 复制代码
   int size = mySet.size(); // 获取set中元素的个数
   bool isEmpty = mySet.empty(); // 判断set是否为空
  1. 删除set中的元素:
c++ 复制代码
   mySet.erase(20); // 删除元素20
   auto it = mySet.find(30);
   if (it != mySet.end()) {
       mySet.erase(it); // 删除迭代器指向的元素
   }
  1. 清空set中的所有元素:
c++ 复制代码
   mySet.clear(); // 清空set中的所有元素
  1. 遍历set中的所有元素:
c++ 复制代码
   for (auto it = mySet.begin(); it != mySet.end(); it++) {
       cout << *it << endl;
   }
   
   for (auto elem : mySet) {
       cout << elem << endl;
   }

第二种方法可以使用C++11中的range-based for循环。

性能比较

使用相同的算法,对vector、list和set进行插入数据和删除数据操作

c 复制代码
//insert number to list,increasing sort
void insert_l(int arg){
	list<int>::iterator iter;
	for(iter = gl.begin();iter!=gl.end();iter++){//ergodic list
		if(arg<*iter){
			gl.insert(iter,arg);//insert number
			break;
		}
	}
	if(iter == gl.end()){
		gl.push_back(arg);//push back number
	}
}
//delete number from list
void delete_l(){
	default_random_engine e1(seed);//new random engine with seed
	while(!gl.empty()){
		uniform_int_distribution<unsigned> u(0,gl.size()-1);
		list<int>::iterator iter = gl.begin();//using iterator
		for(int i=0;i<u(e1);i++){
			iter++;
		}
		gl.erase(iter);//delete number
	}
}

结果

Data Size Vector Time (s) List Time (s)
10000 0.281257 0.527096
50000 6.792 23.2029
100000 26.824 107.947
150000 60.0688 333.013
200000 106.619 807.597

使用set在插入和删除200 000数据总共只用了2.2331秒、而vector用了106.619秒、list用了807.597秒

总结

vector的遍历性能明显比list要快。这是因为vector的元素是存储在一块连续的内存空间中,可以直接通过指针进行访问。而list的元素是通过链表相互连接起来的,无法直接访问,需要遍历整个链表才能访问某个元素,因此遍历性能相对较低。

vector和list在不同场景下有不同的优劣势,需要根据具体情况选择适合的容器。例如,需要随机访问或者高效的遍历操作时,可以选择vector;需要频繁的插入或者删除操作时,可以选择list。

set是基于红黑树实现的,红黑树是一种自平衡的二叉查找树,它具有快速的插入、删除和查找操作的时间复杂度,因此在处理大量数据时,set的性能表现会更好。

相关推荐
时光找茬9 分钟前
【瑞萨AI挑战赛-FPB-RA6E2】+ 从零开始:FPB-RA6E2 开箱测评与 e2 studio 环境配置
c++·单片机·边缘计算
qq_537562679 分钟前
跨语言调用C++接口
开发语言·c++·算法
wjs202419 分钟前
DOM CDATA
开发语言
Tingjct21 分钟前
【初阶数据结构-二叉树】
c语言·开发语言·数据结构·算法
猷咪1 小时前
C++基础
开发语言·c++
IT·小灰灰1 小时前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧1 小时前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q1 小时前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳01 小时前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾1 小时前
php 对接deepseek
android·开发语言·php