C++的STL使用以及底层原理(主要是vector、set、map、multimap、unordered_map)

本文深入探讨STL(标准模板库)的核心组件,包括vector、string、红黑树等数据结构的底层实现原理及应用技巧。从初始化、常用函数到迭代器管理,全面解析STL如何高效处理数据。同时,对比分析set、map与unordered_map的特点和性能差异,为读者提供实用的编程指南。

本篇文章先对 STL的常用函数和使用方法进行介绍,再介绍常用stl的底层实现和区别,总结于侯捷大佬的《STL源码分析》以及视频。
先引用一下侯捷大佬的话:
“使用一个东西,却不明白它的道理,并不高明。”
这也是写这篇文章的原因,记录的同时希望能给别人提供一些帮助。

Vector相关

快捷好用的初始化方式:

int a[6]={1,2,3,4,5,6};
vector<int> v(a,a+6);
//遍历vec,C++11新特性
for(auto iter:vec)
    cout<<iter<<endl;

vector常用函数:

vector<int> v;
v.insert(v.begin()+1,33)//第一个参数是迭代器,将33插入到第二个位置
v.size();
v.pushback();
v[i]//vector重载了[]操作符
v.pop_back();//弹出最后一个元素
v.erase(iter);//删除某个元素,iter代表迭代器
v.erase (v.begin()+i);//删除指定位置(第i个)的元素
  1. vector的迭代器是前闭后开的结构,v.begin()指向第一个元素,v.end()指向最后一个元素的下一个元素;
  2. vector是个单向增长的序列,如果满了,则新申请一个两倍大小的内存空间,将原本的内存复制过去,并且释放原本的内存。(这样做的原因是vector是顺序存储结构,需要一段连续的内存空间,原本的内存空间后面不一定够大)。
  3. vector的迭代器是个指针,而list的迭代器是个类,list的底层实现是双向列表。

string相关

string的底层实现跟vector一样,也是实现了动态扩容,但是string对象的结尾不是以\0结尾的,下面列出一些常用的函数:

string str;
getline(cin, str);//从键盘上输入
string s="Hello world!";
s=s+"s";//+两边至少要有一个string对象
s.insert(1,"ins");//从1位置开始插入“ins”字符串
s.append("ins");//在最后加入“ins”字符串
s.erase(iterator first, iterator last);//删除[first,last)之间的所有字符,返回删除后迭代器的位置
s.erase(iterator it);//删除it指向的字符,返回删除后迭代器的位置
s.find("aa", 0);  //从0开始查找“aa”出现的位置

红黑树相关

因为set和map的底层均为红黑树,所以这里也简单介绍一下红黑树的特性。

  1. 每个节点要么是黑色,要么是红色。
  2. 根节点是黑色。
  3. 每个叶子节点(NIL)是黑色。
  4. 每个红色结点的两个子结点一定都是黑色。
  5. 任意一结点到每个叶子结点的路径都包含数量相同的黑结点。
  6. 插入的节点默认为红色。

Set和Map以及MultiSet和MultiMap

set和map的联系与区别:

  1. 底层都是由红黑树实现的(结构都一样);
  2. 都是按照key排序,并且不允许key重复(通过将变量设置为const来实现);
  3. set是只有一个key,map是一个pair对,包含key和value;

是否有multi的区别:
是否允许key重复,相同key的节点肯定在相邻的地方

Map和Unordered_Map

相同的地方只有他们都是map,区别如下:

  1. 底层实现不同,Map的底层是红黑树,Unordered_Map的底层是哈希表(散列表);
  2. Map是红黑树实现的,所以有排序功能,通过迭代器就可以输出排好序的序列,Unordered_Map没有排序的功能;
  3. Map查找和插入的时间复杂度是O(logn),Unordered_Map是接近O(1),跟哈希函数相关,所以不需要排序的时候用Unordered_Map效率会更高;
    Unordered_Map的数据,如果数据数量超过线性存储表(篮子)的数量查找效率就会降低,所以线性存储表的容量就要增加一倍(类似于vector),是根据经验得到的,没有严谨的数学证明

Set和Map的常用函数

set<int> s;
s.insert();
s.find()==s.end();true的话说明没找到
s.size();
s.erase(iter);
s.erase(iter1,iter2);//删除某一段元素


map<int,string> m;//set有的map也有,就不重复列出来了
m[1]="第一个";
m.insert(pair<int,string>(2,"第二个"));

multiset:
s.count(key)//查找某个元素的个数
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值