代码随想录终极总结之_STL容器使用


拖延了那么久,一直说要搞个总结,来梳理一下STL容器们的函数,今天终于来了。

容器vector

底层原理
vector是动态数组,内存地址中元素存储连续,内存不够时会自动扩容(x1.5/x2都有),必须先初始化才能索引。
~
定义一个迭代器vector::iterator it;迭代器是一种封装了指针功能的结构,可以理解为类似于智能指针
~
初始化方式

vector<type> v0(size,val): 放入size个val
vector<type> v0(v1):       拷贝构造
vector<type> v0(start,end):复制迭代器指向的[start,end)区间元素

子函数们

push_back(): 尾插,O(1)
pop_back():  尾删,O(1)
insert(a, x):a处插入x,O(n)
erase(pos):  删除pos位置元素,O(n)
clear():     全删,O(n)
size():      返回数量,O(1)
empty():     判空,O(1)
resize(n):   重订大小为n,O(n)
begin():      迭代器,指向首个元素
end():        迭代器,指向末尾元素+1
reverse(start,end):反转迭代器指向的[start,end)区间元素

容器deque

底层原理
双端队列deque的底层也是个动态数组,但是和vector不一样,deque采用的是分段存储方式,因此不会有vector自动扩容再重新拷贝的问题。
~
初始化方式

deque<int> dq;            空的
deque<int> dq1(5, 1);     初始51进去
deque<int> dq2(dq1);      拷贝构造
deque<int> dq3(start,end);迭代器指向区间构造,左闭右开

子函数们

push_back():  尾插,O(1)push_front(): 头插,O(1)pop_back():   尾删,O(1)pop_front():  头删,O(1)back():       返回末尾元素,O(1)front():      返回头部元素,O(1)size():       返回元素的个数,O(1)empty():      判断是否为空,O(1)clear():      清空,O(n)erase(pos):   删除pos位置的元素,O(n)insert(n,"xxx"): 在n插入"xxx"O(n)

容器string

底层原理
底层是个字符数组,可以像数组一样操作,最爽的在于string可以直接用+来拼接

初始化方式

string str2("123456789");  生成"1234456789"的复制品
string str3("12345", 0, 3);结果为"123"
string str4("012345", 5);  结果为"01234"
string str5(5, '1');       结果为"11111"
string str6(str2, 2);      结果为"3456789"

子函数们

size()/length():         长度,O(1)empty():                 判空,O(1)substr(pos,length):      从pos起,截取length长度的字符串,返回值是该串,O(n)
clear():                 清空,O(1)insert(n,"xxx"):         在n位置插入"xxx"O(n)
resize(n):               改变字符串的大小,O(n),其中n为字符串的大小。
replace(pos,length,"xxx") 在pos位置开始将length长度替换为"xxx"O(n)
find("xxx")/rfind():     查找"xxx"首次出现的位置,O(n)
compare(str):            比较当前串与str的长度,可自定义,默认返回值大于则大于0O(n)

容器list

底层原理
双向链表list是由多个节点链接形成的,存储上不连续,节点包含自身的值和两个指针,指向前、后。

初始化方式

 list<int>lst(lst1);拷贝构造
 list<int>lst(lst2.begin(),lst2.end());指定范围拷贝构造,左闭右开

子函数们

push_front(val):头插,O(1)
push_back(val): 尾插,O(1)
pop_front():    头删,O(1)
pop_back():     尾删,O(1)
insert(pos,val):在迭代器pos位置插入val,O(1)
erase(pos):     删除迭代器pos指向的元素,O(1)
clear():        全删,O(1)
size():         个数,O(n)
empty():        判空,O(1)
front():        返回头部元素,O(1)
back():         返回尾部元素,O(1)
sort():          排序,默认从小到大,O(n)

sort可以自定义排序规则:

bool cmp(const string& s1, const string& s2) {
    return s1>s2;
}   这就改成从大到小了
list.sort(cmp);

关联式容器set系列

set/multiset

底层原理
二者底层都是红黑树,数据有序,set数据不重复,multiset可重复,二者内部存储的都是数据,其与数组vector关联性非常强,用法也都类似,还可以直接拷贝vector,非常神奇。

初始化方式

set<int> s2(s1); 拷贝构造
set<int> s(v.begin(), v.end());范围拷贝构造,左闭右开

子函数们

insert()   插入元素,O(logN)emplace()  插入元素,O(logN)erase()    删除元素,O(logN)clear()    清空容器,O(N)find(key)  查找元素,O(logN)count(key) 统计元素个数,O(logN)empty()    判空,O(1)size()     返回总个数,O(1)begin():  返回头的迭代器,O(1)end():    返回尾+1O(1)

unordered_set

底层原理
底层依旧是无敌的哈希表,由于哈希的特性,相比于vector,更适用于频繁插入删除的场景
构造方式和set一样,就不提了。

子函数们

insert()   插入pair,O(1)
erase(key) 删除,O(1)
find(key)  查找,O(1)
operator[] 访问值,O(1)
size()     数量,O(1),因为有时刻维护size变量
empty()    判空,O(1)

关联式容器map系列

map/multimap

底层原理
二者底层都是红黑树,数据有序,map的key不重复,multimap可重复,二者内部存储的都是对组pair<type,type>(a,b);
multimap使用根据key值进行的一系列操作,会查到首个该key

子函数们

insert()   插入元素,O(logN)emplace()  插入元素,O(logN)erase()    删除元素,O(logN)clear()    清空容器,O(N)find(key)  查找元素,O(logN)count(key) 统计元素个数,O(logN)empty()    判空,O(1)size()     返回总个数,O(1)begin():  返回头的迭代器,O(1)end():    返回尾+1O(1)

特别的

operator[] 无脑索引,没索引到就插入一个,会爆内存
at(key)    有脑索引,没索引到就out_of_range异常

unordered_map

底层原理
底层是无敌的哈希表,无序,但是key->value这个索引过程非常快,底层根据key通过哈希函数算出哈希值,直接索引。

子函数们

insert()   插入pair,O(1)
erase(key) 删除,O(1)
find(key)  查找,O(1)
operator[] 访问值,O(1)
size()     数量,O(1),因为有时刻维护size变量
empty()    判空,O(1)

容器适配器stack

底层原理
栈stack底层通过使用vector、deque或list等STL容器来实现,默认为deque,可使用stack<int,vector<int>> myStack;来指定底层容器
可用于实现单调栈法,解决找临近的首个大于/小于当前的值,是一种空间换时间的方法。

子函数们

push(): 入栈,O(1)
pop():  出栈,O(1)
top():  返回栈顶元素的引用,可以直接对其进行赋值和修改,O(1)
empty():判空,O(1)
size(): 返回个数,O(1)

这里size为O(1)是因为stack时刻维护一个数量变量,size直接索引到它。

容器适配器queue

底层原理
单向队列queue底层是双向队列deque,只提供单方向出队就变成了queue

子函数们

push(): 入队,O(1)
pop():  出队,O(1)
front():返回队头元素,O(1)
back(): 返回队尾元素,O(1)
size(): 个数,O(1)
empty():判空,O(1)

容器适配器priority_queue

底层原理
优先级队列priority_queue底层是堆heap,堆在作为一个数据结构的时候,其本质是一个有序的完全二叉树

初始化方式

priority_queue<int> q;
priority_queue<int,vector<int>,cmp> q;

第二种定义方式三个参数依次为:1、存储参数类型;2、底层用什么容器构成;3、排序规则

特殊点
1、与普通的队列queue不同,它无法访问front或者back,因为它是堆,大顶堆也好小顶堆也罢,只能访问“顶”top
2、cmp与改变sort()函数的排序方法时不同,此处的cmp要是一个类,不能是一个函数,且return a<b从大到小的大顶堆,如下。

class cmp{
	bool operator(int a,int b){
		return a<b; 比较反直觉,<实现大顶堆,>实现小顶堆
	}
}

子函数们

push(): 入堆,O(1)
pop():  出堆,O(1)
top();   堆顶,O(1)
size(): 个数,O(1)
empty():判空,O(1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值