可以提示插入到标准::地图导致不平衡的树
Can hinted insert to std::map lead to unbalanced tree?
这是否会导致std::map/set
树不平衡(以及随后的搜索性能不佳):
std::set<int> s;
for(int i = 0; i< 1000; ++i)
s.insert(s.end(), i);
?
或者换句话说:"暗示插入"会根据需要重新平衡底层树吗?
Afaik,C++标准并不能保证这一点,但我想知道在这种情况下大多数流行的实现的行为方式。
无论有序关联容器的底层实现如何(标准没有指定,尽管它通常是一个自平衡二叉搜索树),提示插入(iterator insert( const_iterator hint, const value_type& value );
)的要求都可以通过以下简单的算法来满足:
-
将值与 *hint 和 *prev(hint) 进行比较
-
如果它适合它们之间,请将其插入那里。
-
否则,请忽略该提示。
只要prev(hint)
是摊销常量时间,只要hint
是正确的,该算法就是摊销常量时间。("正确"是指插入点之后的位置。
如果提示不正确,则忽略提示是完全可以接受的,因此提供不正确的提示不会导致数据结构有任何差异;它仍然像插入之前一样平衡(对数可访问)。但是提供不正确的提示会强制计算 O(1) 额外的比较,因此只有在提示通常正确的情况下,对于"通常"的某个值,才应使用提示版本的插入。
一个常见的用例是,当已经搜索了要插入的条目时,因此插入位置是肯定的。这避免了在插入之前需要完成某些操作时搜索两次的开销,而不会在其他进程修改find()
和暗示insert()
之间的set
时牺牲安全性(当然,假设适当的锁定)。
No.树将保持平衡,因为这是std::set
不变性的一部分。 否则,它无法保证对数查找时间(最坏的情况是线性的)。
"提示"只是一个提示 - 不是"在此处插入"的要求
std::map
和std::set
被实现为红黑树。
这意味着任何子树的最长分支不超过该子树最小分支(也适用于根)大小的两倍。
因此,您可以期望查找操作花费的时间不超过完美平衡树的两倍。
插入和删除操作可能需要更长的时间(因为树可能会重新平衡),但仍O(log n)
(未摊销)。
- 为什么不;名字在地图上是按顺序排列的吗
- 我正在尝试制作一个自平衡机器人,但编译时存在错误。我不知道如何解决它
- 为什么不插入地图?
- OpenMP 和不平衡嵌套循环
- 如何将地图作为不可变地图传递?
- OpenMP C++:并行化 for 循环的负载不平衡
- 可以提示插入到标准::地图导致不平衡的树
- 删除字符串中不平衡的括号
- 为什么我的递归快速排序算法有如此不平衡的分区
- 使用 .Net 4.0 时出现堆栈不平衡错误,但在使用 .Net 2.0 时不调用堆栈不平衡错误
- 为什么是我的AVL树删除功能不平衡
- 试图捕获不平衡的分隔符.我需要显示与之关联的行号.遇到问题和我的测试文件
- 正在打印不平衡的二进制树
- 在 g++ 中使用 __attribute__ 的不平衡括号
- 由于指针导致堆栈不平衡
- 使用 GDB 的 Python 漂亮打印不支持地图的索引运算符 []
- 我不明白地图插入上的此错误
- 不平衡随机数生成器
- 元素看起来像在地图中,但它不在地图中
- 在不增加地图大小的情况下检查地图内容