C++ STL容器 常用操作大全

C++ STL容器 常用操作大全

序列容器

顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定。包含:(forword_list,list,queue,priority_queue,stack,deque,vector,array(虽然他被归为序列容器,但是并不满足序列的所以要求!))。

  • 序列的要求
X a(n,t)  //声明一个名为a的有n个t组成的序列
X(n,t)     //匿名序列(这里我们不做过多的解释)
X a(i,j)   //声明一个名为a的序列,并且初始化[i,j)
的内容
X(i,j)      //匿名序列
v.insert()   //由于insert重载方法比较多
   1.v.insert(p,t)//将t插到迭代器p的前面
   2.v.insert(p,n,t)//将n个t插入迭代器p之前
   3.v.insert(p,i.j)//将区间[i,j)的元素插入到迭代器p之前
v.erase(t,k)
   1.v.erase(t,k)//删除[t, k)之间的元素
   2.v.erase(p)//删除迭代器p指向的元素
v.chear===v.erase(begin(),end());

Vector

  • 概述
    动态数组,在内存中具有连续的储存空间,在堆上分配内存,支持快速随机访问,在中间插入和删除慢,但在末尾插入和删除快。一个vector的容量永远大于或等于其大小,一旦容量等于大小,便是满载,下次再有新增元素,整个vector容器就得另觅居所。因此,对vector的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就都失效了。

  • 定义和初始化

    vector<int> v;//默认初始化
    vector<int> v(v1);//用v1初始化v
    vector<int>v(v1.begin(),v1.end());//用v1初始化v
    vector<int> v(10);//定义一个大小为10的数组!
    vector<int> v(10,1)//定义个全为1而且长度为10的数组
    
  • 方法

	a.front() //返回第一个元素
	a.back() //末尾元素
	c.begin() 返回一个迭代器,它指向容器的第一个元素

	c.end() 返回一个迭代器,它指向容器的最后一个元素的下一个位置
	c.rbegin() //返回一个逆序迭代器,它指向容器的最后一个元素
	c.rend() 返回一个逆序迭代器,它指向容器的第一个元素前面的位置
	v,push_back() //增
	v.insert() //插入
		1、v.insert(p, t) //将t插到p的前面
		2、v.insert(p, n, t) //将n个t插入p之前
		3、v.insert(p, i, j) //将区间[i,j)的元素插入到p之前
	v.pop_back();//删除最后一个元素
	v.erase(t,k)
    	1、v.erase(t,k)//删除[t,k)之间的元素
   		2、v.erase(p)//删除p指向的元素
   	v.chear()==v.erase(begin(),end());//删除所有元素
  • 遍历
//下标法
int length = v.size();
for(int i=0;i<length;i++)
{
cout<<v[i];
}
cout<<endl;
//迭代器法
vector<int>::const_iterator iterator = v.begin();
 for(;iterator != v.end();iterator++)
{
 cout<<*iterator;
 }
  • 时间复杂度
    头部插入删除:O(N)

    尾部插入删除:O(1)

    中间插入删除:O(N)

    查找:O(N)

    查找通过algorithm库中的find函数,其调用形式为
    find(start,end,value)
    返回值为对应的迭代器,若不存在则返回a.end()
    `

deque

  • 概述
    deque是double ended queue的缩写,是一个动态数组,可以向两端发展(双向开口的连续线性空间),因此无论在头部或者尾部安插元素都十分迅速,在中间按插元素则比较费时,因为必须移动其他元素。
    双端队列的元素被表示为一个分段数组,容器中的元素分段存放在一个个大小固定的数组中,此外,容器还需要维护一个存放这些数组首地址的索引数组。如下图所示:
    deque示意图

    初始化与定义已经在序列要求里面,而且方法与vector类似,只是多了push_front()(),pop_front(),这里不做过多的阐述。

  • 时间复杂度分析
    头部尾部插入删除:O(1)

    中间插入删除:O(N)

    查找:O(N)

list

  • 概述
    链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
    List容器是一个双向链表。

  • 特点
    1)没有预留空间的习惯,所以每分配一个元素都会从内存中分配,每释放一个元素都会释放其占用的内存

    2)任何地方插入删除的效率都很高,不需要移动内存,也就不需要在移动过程中对每个元素进行构造和析构,常用来做随机插入和删除的容器

    3)访问首尾元素最快

  • 独有方法

void sort()   //使用<运算符对链表进行排序,时间复杂O(NlogN)
void merge(list<T,Alloc>&x)  //将x与调用链表合并,要求:两个链表必须要已经排好序!元素将保存在调用链表中,x为空,这个时间复杂度为线性!
void remove(const T &val)//删除val的所有实例
void splice(iterator pos,list<T,Alloc>x)//将链表x的内容加到pos的前面,时间复杂度为固定时间
//insert与splice的区别:insert将list对象的副本插入到目标区域中,而splice是将该对象直接移到目标地址。通俗地说前者是复制,粘贴。后者是剪切,粘贴。
	1、void splice( iterator pos, list &lst );   
	2、void splice( iterator pos, list &lst, iterator del );  
	3、void splice( iterator pos, list &lst, iterator start, iterator end ); 
void unique() //去重,线性时间
  • 时间复杂度分析
    任何位置的插入删除:O(1)(假设告诉了你插入删除的位置,不需要你线查找再删除)

    查找:O(N)

序列容器适配器

包括stack、queue、priority_queue

  • 都支持的操作
A a; //创建一个名为a的空适配器
关系运算符 ==、!=、<、<=、>、>=;这些运算符都返回底层容器的比较结果
a.empty()
a.size() //元素数目
swap(a, b)或a.swap(b) //交换a和b的内容,a和b必须有相同类型,底层类型也相同

stack

  • 概述
    stack是一种先进后出(First In Last Out,FILO)的数据结构。stack不提供遍历功能,也不提供迭代器。
    在这里插入图片描述
  • 方法
push(elem);//向栈顶添加元素
pop();//从栈顶移除第一个元素
top();//返回栈顶元素

queue

  • 概述
    queue所有元素的进出都必须符合”先进先出”的条件,只有queue的顶端元素,才有机会被外界取用。queue不提供遍历功能,也不提供迭代器。
    在这里插入图片描述
  • 方法
	q.pop();//删除首元素,但不返回元素值
	q.front();//返回首元素,但不删除
	q.back();//返回尾元素
	q.push(item);//在尾端添加一个item元素
	q.emplace(arg);//在尾端添加一个由arg构造的元素

priority_queue(优先队列)

  • 概述
    与queue基本一样,但是他的最大元素被移动到队首(生活不总是公平对,队列也一样),内部区别在于底层结构不一样,他用的是vector,当然我们可以修改确定拿个元素放在队首的比较方式!
priority_queue<int> X //大根堆,默认初始化

priority_queue<int, vector<int>, greater<int>> x  //小根堆,运用了预定义函数greater<int>!
  • 方法
    支持与queue一样的方法。

关联容器

set

  • 概述
    set由红黑树实现,其内部元素依照其值自动排序,每个元素只出现一次,不允许重复(红黑树是平衡二叉树的一种)
  • 特点
    1)元素有序
    2)无重复元素
    3)插入删除操作的效率比序列容器高,因为对于关联容器来说,不需要做内存的拷贝和内存的移动
    4)对于迭代器来说,不可以修改值
  • 方法
size();//返回容器中元素的数目
empty();//判断容器是否为空
insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素。
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);//查找键key的元素个数
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。
  • 时间复杂度分析
    增删改查近似:O(log N)

multiset

  • 概述
    multiset和set相同,只不过它允许重复元素,也就是说multiset可包括多个数值相同的元素。这里不再做过多介绍。

map

  • 概述
    map由红黑树实现,其元素都是键值对,每个元素的键是排序的准则,每个键只能出现一次,不允许重复。
  • 特点
    1)元素为键值对形式,键和值可以是任意类型
    2)因为key有序,所以可以通过二分对key进行快速查找
    3)增加和删除结点对迭代器的影响很小,除了当前结点是迭代器指向的结点
    4)对于迭代器来说,可以修改值,但是不能修改key
  • 方法
size();//返回容器中元素的数目
empty();//判断容器是否为空
map.insert(...); //往容器插入元素,返回pair<iterator,bool>
map<int, string> mapStu;
// 第一种 通过pair的方式插入对象
mapStu.insert(pair<int, string>(3, "小张"));
// 第二种 通过pair的方式插入对象
mapStu.inset(make_pair(-1, "校长"));
// 第三种 通过value_type的方式插入对象
mapStu.insert(map<int, string>::value_type(1, "小李"));
// 第四种 通过数组的方式插入值
mapStu[3] = "小刘";
mapStu[5] = "小王";
clear();//删除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg,end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(keyElem);//删除容器中key为keyElem的对组。
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;/若不存在,返回map.end();
count(keyElem);//返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1。对multimap来说,值可能大于1。
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。
  • 时间复杂度分析
    增删改查基本是O(log N)

multimap

  • 概述
    multimap和map相同,但允许重复元素,也就是说multimap可包含多个键值(key)相同的元素。这里不再做过多介绍。

补充

  • list、map、set、unordered_map、unordered_set的迭代器不支持加减法,只支持++、–
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值