Day-12
问题
map和set的区别?分别是怎么实现的。
参考答案
参考:《STL源码剖析》chapter5 关联式容器set与map
map
和set
的底层都是通过红黑树
实现的,map
和set
的区别有:
map
中的元素是key-value
(关键字-值)对;而set
中的元素是关键字;map
和set
都不允许插入重复元素。set
的迭代器是const
的(底层是通过使用红黑树的const iterator
),所以不允许修改元素的值;map
允许修改value
的值,但是不允许修改key
的值;map
和set
都不允许修改关键字,因为底层的红黑树需要依靠关键字保持有序性。map
支持下标操作,而set
不支持下标操作。需要注意的是map
的下标操作是通过insert
操作实现的,也就是尝试插入一个查询键值对,如果存在该键值对存在则返回。
进阶: 红黑树
参考:《STL源码剖析》chapter5 关联式容器概述和红黑树简介
二叉搜索树
:二叉搜索树的任何节点的键值一定大于等于其左子树的任何一个节点的键值,同时小于等于其右子树中的任何一个节点的键值。
平衡二叉搜索树
:平衡的意思是没有一个节点的深度过大,常见的有AVL-tree
(自平衡二叉搜索树),RB-tree
(红黑树)。
红黑树
是平衡二叉树,其满足以下特点:
- 根节点一定是黑色的
- 每个节点不是黑色就是红色
- 父子节点不能同时是红色
- 任意节点到底层的NULL节点,所含黑节点数目一定相同(
黑高
相同)
由于含有n
个节点的红黑树
的高度为
O
(
l
g
n
)
O(lgn)
O(lgn),所以红黑树的插入和删除的时间复杂度都是
O
(
l
g
n
)
O(lgn)
O(lgn)`.
为什么map
和set
的底层采用红黑树而不是AVL树实现?
因为红黑树相比于AVL树在插入删除中的平均时间复杂度要小于AVL树的插入删除的平均时间复杂度。
由红黑树的特点2和特点4我们可以知道,红黑树的每一条到叶子节点的路径至少有50%的概率时黑节点,而插入和删除在遇到黑节点的时候复杂度降为 O ( 1 ) O(1) O(1),这就导致红黑树插入删除的平均时间复杂度应该小于或等于AVL树插入删除的平均时间复杂度的一半。