C++ STL 中是不是有任何数据结构用于执行 log(n) 中第 k 个元素的插入、搜索和检索?
Posted
技术标签:
【中文标题】C++ STL 中是不是有任何数据结构用于执行 log(n) 中第 k 个元素的插入、搜索和检索?【英文标题】:Is there any data structure in C++ STL for performing insertion, searching and retrieval of kth element in log(n)?C++ STL 中是否有任何数据结构用于执行 log(n) 中第 k 个元素的插入、搜索和检索? 【发布时间】:2014-05-28 08:21:24 【问题描述】:我需要一个 c++ STL 中的数据结构来执行 log(n) 中第 k 个元素的插入、搜索和检索
(注意:k是变量,不是常数)
我有一门课
class myClass
int id;
//other variables
;
我的比较器只是基于这个id,没有两个元素会有相同的id。
有没有办法使用 STL 来做到这一点,或者我必须手动编写 log(n) 函数以在任何时间点按排序顺序维护数组?
【问题讨论】:
答案假设(可能正确)您想要检索给定容器的许多“kth”元素(即k
在容器的生命周期内的运行时变化)。这值得在问题中明确说明,或者在您的要求不那么苛刻时进行纠正(例如,每个容器一个 k
,在编译或构建时指定) - 然后有更快的解决方案。
您需要“STL”吗? o.O 你的意思是标准容器,来自标准库吗?
在 C 中尝试 #include "libavl.h"
adtinfo.org
我编辑了这个问题。请删除反对票 :)
【参考方案1】:
Afaik,没有这样的数据结构。当然,std::set
与此接近,但并不完全如此。它是一棵红黑色的树。如果这棵红黑树的每个节点都用树权重(以该节点为根的子树中的节点数)进行注释,那么retrieve(k)
查询将是可能的。由于没有这样的权重注释(因为它占用了宝贵的内存,并且由于必须更新权重而使插入/删除变得更加复杂),因此不可能使用任何搜索树有效地回答这样的查询。
如果要构建这样的数据结构,请使用传统的搜索树实现(红黑、AVL、B-Tree,...),并为每个节点添加一个权重字段,用于计算其子树中的条目数.那么搜索k-th
这个入口就很简单了:
草图:
-
检查子节点的权重,找到权重最大的子节点
c
(从左开始累加)不大于k
从k
中减去c
剩下的所有孩子的权重。
下降到c
并递归调用此过程。
在二叉搜索树的情况下,算法非常简单,因为每个节点只有两个孩子。对于 B 树(可能更有效),您必须考虑节点包含的子节点数量。
当然,您必须在插入/删除时更新权重:从插入/删除位置沿树向上,并递增/递减每个节点的权重直至根。此外,在进行旋转(或在 B 树情况下拆分/合并)时,您必须交换节点的权重。
另一个想法是跳过列表,其中跳过的元素带有它们跳过的元素数量的注释。但是这个实现并不是微不足道的,因为你必须在插入或删除的元素上方更新每个跳跃的跳跃长度,所以调整二叉搜索树更容易恕我直言。
编辑:我找到了一个 2-3-4 树(B-tree)的 C 实现,查看本页底部的链接:http://www.chiark.greenend.org.uk/~sgtatham/algorithms/cbtree.html
【讨论】:
平衡的二叉搜索树可以轻松做到这一点:|但是为什么 C++ stl 中没有任何 BBST 实现呢? @cegprakash:你什么意思?一个完美平衡的二叉搜索树?那么答案是:因为它不能有效地更新。 @cegprakash: 那么你不能插入O(log n)
:( 但是,retrieve(k)
甚至会是 O(1),只需使用 []
:)
@cegprakash:std::vector
是一个数组,而不是一个链表,所以你的说法不正确。只需检查插入的文档:cplusplus.com/reference/vector/vector/insert 引用:插入的元素数量线性(复制/移动构造)加上位置后的元素数量(移动)。
这个答案描述的结构通常称为order statistic tree。【参考方案2】:
你不能用简单的数组或任何其他内置容器来实现你想要的。您可以使用更高级的数据结构,例如跳过列表或修改后的红黑树(std::set
的支持数据结构)。
您可以在线性时间内获取任意数组的第 k 个元素,如果数组已排序,您可以在恒定时间内完成,但插入仍然需要移动所有后续元素,这在最坏的情况下是线性的.
至于std::set
,您需要在每个节点上存储额外的数据才能有效地获取第 k 个元素,不幸的是您无法修改节点结构。
【讨论】:
以上是关于C++ STL 中是不是有任何数据结构用于执行 log(n) 中第 k 个元素的插入、搜索和检索?的主要内容,如果未能解决你的问题,请参考以下文章