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)?

本文关键字:元素 插入 检索 搜索 数据结构 是否 STL c++ log      更新时间:2023-10-16

我需要一个c++ STL中的数据结构来执行插入,搜索和检索log(n)中的第k个元素

(注意:k是一个变量而不是常量)

我有一个类,像

class myClass{
  int id;
  //other variables
};

和我的比较器只是基于这个id,没有两个元素具有相同的id。

是否有一种方法可以使用STL来做到这一点,或者我必须手动编写log(n)函数来维护数组在任何时间点的排序顺序?

很抱歉,没有这样的数据结构。当然,std::set和这个很接近,但又不完全接近。它是一棵红黑的树。如果该红黑树的每个节点都用树权值(在该节点上扎根的子树中的节点数)进行注释,则可以执行retrieve(k)查询。由于没有这样的权重注释(因为它占用宝贵的内存,并且由于必须更新权重而使插入/删除更加复杂),因此使用任何搜索树都不可能有效地回答这样的查询。

如果您想构建这样的数据结构,请使用传统的搜索树实现(红黑、AVL、B-Tree等),并向每个节点添加一个权重字段,用于计算其子树中的条目数量。然后搜索k-th条目非常简单:

素描:

  1. 检查子节点的权值,找出权值最大的子节点c(从左开始)且不大于k
  2. k中减去c剩下的所有子元素的权重。
  3. 下降到c并递归调用这个过程。

在二叉搜索树的情况下,算法非常简单,因为每个节点只有两个子节点。对于b树(可能更有效),您必须考虑节点包含的子节点数量。

当然,您必须更新插入/删除时的权值:从插入/删除位置向上移动树,并增加/减少每个节点的权值,直到根节点。此外,在进行旋转(或在b树的情况下进行拆分/合并)时,必须交换节点的权重。

另一个想法是一个跳过列表,其中的跳过用它们跳过的元素数量进行注释。但是这个实现并不简单,因为您必须更新插入或删除的元素上方的每个跳跃的长度,因此调整二叉搜索树就不那么麻烦了。

编辑:我发现了一个2-3-4树(B-tree)的C实现,查看本页底部的链接:http://www.chiark.greenend.org.uk/~sgtatham/algorithms/cbtree.html

您无法通过简单的数组或任何其他内置容器实现您想要的功能。您可以使用更高级的数据结构,例如跳跃表或修改过的红黑树(std::set的后台数据结构)。

你可以在线性时间内得到任意数组的第k个元素,如果数组是排序的,你可以在常数时间内完成,但插入仍然需要移动所有后续元素,这在最坏的情况下是线性的。

对于std::set,您将需要在每个节点上存储额外的数据,以便能够有效地获得第k个元素,不幸的是,您无法修改节点结构。