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(从左开始累加)不大于kk 中减去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 个元素的插入、搜索和检索?的主要内容,如果未能解决你的问题,请参考以下文章

使用 C++ Boost 或 STL 和 Mysql 存储和检索图像

用于位图管理的 C++ STL 类

函数返回迭代器以构造 STL 容器

Python中是不是有类似于C++ STL map的结构?

C 等价于 C++ STL [重复]

STL重载运算符