【发布时间】:2017-10-13 13:29:00
【问题描述】:
我最近遇到了一个问题。我想获取std::set 元素的相对索引。例如,如果std::set 存储{1, 2, 4, 6, 9, 15},我想找到元素{4} 并有效地获取它的相对索引{2}。当然,我可以写std::distance(myset.begin(), myiterator),但是这个操作的复杂度是O(n*logn)。如果我可以访问std::set 的真正红黑树,我会运行rb_tree_node_pos(见下文),即O(logn)。这正是相对索引。有谁知道我怎样才能得到真正的树?
下面是代码示例:
#include <iostream>
#include <set>
using namespace std ;
int rb_tree_node_pos(rb_tree_node *node) {
//function that finds relative index of tree node
if (node->parent==NULL) return rb_tree_size(node->left) ;
else return rb_tree_node_pos(node->parent)+rb_tree_size(node->left)+1 ;_
}
int main () {
set<int> myset ;
//... reading some data in myset
int find_int ;
cin >> find_int ;
set<int>::iterator myit=myset.find(find_int) ;
int find_index=distance(myset.begin(), myit) ; // O(n*log(n)), to slow!!!
find_index=rb_tree_node_pos(myit->get_rb_tree()) ; // that's O(logn)
cout << find_index << endl ;
return 0 ;
}
一般来说,我希望数据结构能够维护以下操作:1. 插入元素,2. 删除元素,3. 打印出元素的相对索引。我认为有一种方法可以从 STL 中“挖掘”它。
【问题讨论】:
-
最好使用排序数组和二分查找。
-
但是如何在有序数组中有效地插入一些东西?
-
请注意,红黑树是一个实现细节,这意味着您的 std::set 甚至可能不会被实现为红黑树。这个问题闻起来像 XY 问题。您真正想要解决的问题是什么?
-
可以在不维护每个节点的子树大小的情况下实现红黑树,因此使用“真正的”rb-tree 可以做的最好的事情是 O(n)。
-
真正的问题:“我想要的数据结构将保持以下操作:1.插入元素,2.删除元素,3.打印出元素的相对索引”。我不想自己写吧。
标签: c++ stl set binary-tree red-black-tree