【问题标题】:How to access kth element in a c++ std::set in logarithmic time?如何以对数时间访问 c++ std::set 中的第 k 个元素?
【发布时间】:2019-10-19 10:20:51
【问题描述】:

我有一个数字列表,我需要在其中支持两种类型的多个查询:我可以删除一个元素,或者我需要在剩余列表中找到第 k 个最小的(每个查询中的 k 可以不同)元素。

因为如果我使用自平衡 BST,这两个都可以在对数时间内得到支持,并且由于 std::set 是通过自平衡 BST 实现的,所以应该有一个 API 可以使用它在对数时间内访问第 k 个元素。如果没有这样的方法:

i) 为什么?对我来说,这似乎是一个常见的用例。

ii) 实现自平衡树是我唯一的希望还是我可以使用其他方法使其工作?

【问题讨论】:

  • std::set 通常使用树实现是一个实现细节。 C++ 标准只指定容器interface 而不是实现。如果你明确需要一个树结构,你应该自己实现它。
  • 如何在对数时间内访问普通 BST(不存储子树的大小)中的第 k 个最小元素?
  • std::set 和其他关联容器通常使用红黑树实现,它们通常不知道每个子树的大小,只知道每个子树的最大深度的上限和下限。

标签: c++ algorithm data-structures binary-search-tree


【解决方案1】:

您需要使用基于策略的数据结构。

To delete you can use : erase(T elementToerase)
To find the kth element : find_by_order(int k) where k is 0 based indexing
                          it returns iterator to kth element.

这两个操作都是 O(logn)

更多详情:https://gcc.gnu.org/onlinedocs/libstdc++/manual/policy_data_structures_design.html

【讨论】:

    【解决方案2】:

    自平衡 BST,应该有一个 API 可以使用它在对数时间内访问第 k 个元素

    我)为什么[不]?

    据我所知,不存在一种算法可以在对数时间内找到一个简单的平衡 bst 中的第 n 个元素。

    这可能会帮助您了解可以增强平衡的 bst 以实现对数运算。这种增广树的名称是“订单统计树”。

    ii) 实现自平衡树是我唯一的希望还是我可以使用其他方法使其工作?

    这不是唯一的选择。与往常一样,您可以使用现有的实现。

    【讨论】:

    • 我想我记错了。这只是订单统计数据的近似值。 .对不起
    猜你喜欢
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多