C++ 是否有任何boost/stl容器支持以下操作?
我正在寻找能够提供以下功能的stl/boost容器:C++ 是否有任何boost/stl容器支持以下操作?,c++,c++11,boost,stl,C++,C++11,Boost,Stl,我正在寻找能够提供以下功能的stl/boost容器: 按排序顺序自动插入元素。(日志n) 从起始节点返回元素的索引/深度。(日志n) 如果没有,实现这一目标的最佳方式是什么?我正在考虑使用双链接列表的解决方案。这是解决这个问题的好选择吗?二叉树(B树)在平均情况下具有对数插入和检索(相当于深度计数)时间,并且在按顺序行走时自然排序 不幸的是,如果B-树不平衡(最坏情况),则B-树的插入/检索时间可能退化为线性。如果这是一个问题,你应该考虑一个红黑树,它不会消除问题,但减轻它,同时保持插入时间对数
请记住,链表具有线性插入时间,即使是双插入时间。
std::map
和std::set
根据标准保证O(log(N))插入和搜索,它们也满足排序顺序条件。请参阅C++标准AT .
在@StefanoSanfilippo建设性评论后更新:
但是请记住,这些容器只允许唯一的键/元素。如果有多个值,则必须求助于std::multimap
和std::multiset
。这些容器的属性与std::map
和std::set
几乎相同,但允许多个键/元素
关于索引/深度问题,就STL容器而言,不能保证std::map
和std::set
实现为二叉树,因此没有访问树属性(如深度和索引)的接口(请参阅)。做一个有根据的猜测,我认为boost的树状容器也是如此
更新-引用@Mooing Duck的评论:
boost树也没有获取索引的方法
更新 你需要一份工作。C++标准库没有任何,也不提供实现一个简单的方法,参见
libstdc++
中作为扩展提供强>
- 或
(原始答复:)
O(n)
如果没有:实现这一目标的最佳方式是什么?我在想一个办法
解决方案使用双链接列表。这是解决这个问题的好选择吗
有问题吗
std::list
是一个双链接列表,但只能实现线性时间插入<代码>标准::列表是一个巨大的性能杀手,因为它对缓存的使用不当
使用它可能会更好,因为它也只提供线性时间插入,但由于缓存的出色使用(多亏了硬件预取器),它的速度可能会让您大吃一惊。作为奖励,您可以获得随机访问迭代器,因此,如果您已经拥有元素,则可以在O(1)
time中找到索引
如果这两种复杂性要求都是必须的,那么我认为没有比实现自平衡二叉搜索树并在每个父节点上存储子树大小更简单的方法了。维护这些额外信息不会破坏O(logn)
的复杂性。即使您从std::map
的一个实现开始(不保证是红黑树,但在libstdc++
中,它是开源的),实现它也是一项重要而非琐碎的工作
我还想到一件事:你的使用模式是什么?您是否一个接一个地进行插入和索引查找完全是随机的?如果没有,或者至少主要没有,那么您可能会在这两者之间切换数据结构,并使用其中一个stl或boost容器。排序双链接列表的插入成本为O(#list/2)。无论如何,为什么一定要对它进行排序呢?一个精心创建的容器类将是平衡的,因此深度除了海量数据集之外将不相关。在这一点上,你可能会更倾向于使用hashI,因为我不知道CS世界或“O(n)等”世界,但对我来说,它听起来像是一个树容器,而不是双链表。在现实生活中,通常使用O(log(n))插入要比使用O(1)插入慢,最后使用O(nlog(n))排序。。我总是只使用vector和std QuickSort。第一个要求意味着您需要一个关联容器。但是在2。您需要O(logN)查找还是随机访问?换句话说,你想找到一个元素还是跳转一些元素?
std::set
对元素的唯一性有一个限制,这对于OP来说可能是不可接受的。@StefanoSanfilippo感谢你的建设性评论,我将添加一个更新。boost树也没有办法获得索引,虽然我已经编写了一个基于索引的树容器,但是如果我使用multiset,它是可行的。查找索引将变成O(n)。@ VivikGoL是对数,参见C++标准[第743页,表102。“从起始节点返回元素/深度元素”。这是一个特性,而不是复杂性保证。它保证了STD::STAT:STD::MAP等的插入和查找具有O(Logn)C。