我需要c ++ STL中的数据结构来执行log(n)中第k个元素的插入,搜索和检索
(注意:k是变量而不是常数)
我有一个像
这样的课程class myClass{
int id;
//other variables
};
我的比较器只是基于这个id,没有两个元素具有相同的id。
有没有办法使用STL执行此操作,或者我手动编写log(n)函数以在任何时间点按排序顺序维护数组?
答案 0 :(得分:5)
Afaik,没有这样的数据结构。当然,std::set
接近于此,但并不完全。这是一棵红黑树。如果此红黑树的每个节点都使用树权重(使用以此节点为根的子树中的节点数)进行注释,则可以进行retrieve(k)
查询。由于没有这样的权重注释(因为它需要宝贵的内存并且因为必须更新权重而使插入/删除变得更复杂),所以不可能用任何搜索树有效地回答这样的查询。
如果要构建这样的数据结构,请使用传统的搜索树实现(红黑,AVL,B树,...),并为每个节点添加权重字段,以计算其子树中的条目数。然后搜索k-th
条目非常简单:
草图:
c
k
k
减去c
所有儿童的所有权重。c
并递归调用此过程。在二叉搜索树的情况下,算法非常简单,因为每个节点只有两个子节点。对于B树(可能更有效),您必须考虑节点包含的子节点数。
当然,您必须更新插入/删除时的权重:从插入/删除位置向上移动树,并将每个节点的权重递增/递减到根。此外,在进行旋转(或在B树情况下拆分/合并)时,必须交换节点的权重。
另一个想法是跳过列表,其中跳过用他们跳过的元素数量注释。但是这个实现并不简单,因为你必须在插入或删除的元素之上更新每个跳过的跳过长度,因此调整二叉搜索树的麻烦不那么恕我直言。
编辑:我找到了2-3-4树(B树)的C实现,请查看本页底部的链接:http://www.chiark.greenend.org.uk/~sgtatham/algorithms/cbtree.html
答案 1 :(得分:0)
使用简单数组或任何其他内置容器无法实现您想要的效果。您可以使用更高级的数据结构,例如跳过列表或修改的红黑树(std::set
的支持数据结构)。
你可以在线性时间内获得任意数组的第k个元素,如果数组已经排序,你可以在恒定时间内完成,但是插入仍然需要移动所有后续元素,这在最坏的情况下是线性的。
对于std::set
,您需要在每个节点存储额外的数据才能有效地获取第k个元素,遗憾的是您无法修改节点结构。