一文带你看懂容器(序列式容器,关联式容器,无序关联式容器)

容器

作用:存放数据

序列式容器

array

静态数组,大小固定的数组

vector

动态数组,支持随机访问迭代器,逻辑结构和物理结构相似

在GCC下两倍增长,在VC下1.5倍增长

deque

双端队列,支持随机访问迭代器

逻辑结构:连续空间,双端开口

物理结构:在内存中由多个片段构成的,片段内部是连续的,但是片段之间不连续。

forward_list

单链表,支持前向访问迭代器

list

双向链表,支持双向访问迭代器

物理结构:循环双向链表

逻辑结构:双向链表

线性容器总结

位置使用
需要频繁的在容器中间位置添加/删除元素list
需要频繁的在容器头部位置添加/删除元素deque/list
需要频繁的在容器尾部位置添加/删除元素vector/deque/list
需要频繁的在容器头部,尾部添加/删除元素deque/list
需要频繁地访问任意位置上的元素vector/deque

关联式容器

共性

底层实现都是红黑树,红黑树是一种近似的平衡二叉树

查找元素的时间复杂度为O(LogN) 二分查找

默认情况下按照升序的方式进行排列

不能修改关键字的值

支持的是双向访问迭代器

set

不能存储重复的关键字Key

不支持下标访问运算符

模板:

template<
	class Key,
	class Compare = std::less<Key>,
	class Allocator = std::allocator<Key>
> class set;

初始化:

set<int> number={1,12,325,446,47};

set不支持下标与修改

set针对自定义类型,必须要实现Compare,也就是std::less或者std::greater

multiset

template<
	class Key,
	class Compare = std::less<Key>,
	class Allocator = std::allocator<Key>
> class multiset;

可以存储重复的Key

与set的区别

set与multiset的初始化、遍历、查找、删除的使用都一样,都不支持下标访问、都不支持修改。对于
insert插入而言,multiset肯定可以插入成功,所以二者返回类型不一样,至于插入迭代器返回与大括
号类型都是一样的。

map

template<
	class Key,
	class T,
	class Compare = std::less<Key>,
	class Allocator = std::allocator<std::pair<const Key, T> >
> class map;

1,存放的关键字Key不重复,按照key值升序

2,支持下标访问运算符

3,存放的元素是一个pair类型,key与value值,key是唯一的,不能重复的,但value值重复与否是没关系的

初始化:

map<int,string> number={
    {3,"武汉"},
    {4,"上海"},
    {5,"武汉"},
    pair<int,string>(6,"北京"),
    pair<int,string>(7,"天津"),
    make_pair(8,"杭州"),
    make_pair(9,"重庆"),
}

multimap

template<
	class Key,
	class T,
	class Compare = std::less<Key>,
	class Allocator = std::allocator<std::pair<const Key, T> >
> class multimap;

可以存储重复的Key

multimap不支持下标访问,key值相同的时候,value有可能不一样

无序关联式容器

底层实现——哈希表

哈希函数

通过key值,可以找到key值对应的value

size_t idx=H(key);
哈希函数的设计

直接定址法,平方取中法,数字分析法,除数取余法。

哈希冲突

不同key值,对应相同的value值

key1不等于key2,但是
H(key1)=H(key2)
哈希冲突的解决方式

1,开放定址法

2,链地址法(推荐使用这种方法,STL中使用的方法)

3,再散列法

4,建立公共溢出区
在这里插入图片描述

存放的元素是无序

针对自定义类型必须给出hash函数,必须重载operator=

unordered_set

template<
	class Key,
	class Hash = std::hash<Key>,
	class KeyEqual = std::equal_to<Key>,
	class Allocator = std::allocator<Key>
> class unordered_set;

不能存储关键字相同的元素

不能用下标访问运算符

unordered_set<int> qq ={1,9,9,3,0,9,5,6,2,2};

unordered_multiset

unordered_set<int> qq ={1,9,9,3,0,9,5,6,2,2};

可以存放关键字相同的元素

unordered_map

template<
	class Key,
	class T,
	class Hash = std::hash<Key>,
	class KeyEqual = std::equal_to<Key>,
	class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;

不能存放关键字相同的元素

可以使用下标访问运算符

unordered_multimap

可以存放关键字相同的元素

如何选择合适的容器

如果元素是连续存储的

序列式容器,vector

查找数据的时候,时间复杂度

O(1):四个无序关联式容器 vector

O(logN):四种关联式容器

可以使用下标

vector,deque,map,unordered_map

下标具有插入操作的

map或者unordered_map

以使用下标访问运算符

unordered_multimap

可以存放关键字相同的元素

如何选择合适的容器

如果元素是连续存储的

序列式容器,vector

查找数据的时候,时间复杂度

O(1):四个无序关联式容器 vector

O(logN):四种关联式容器

可以使用下标

vector,deque,map,unordered_map

下标具有插入操作的

map或者unordered_map

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值