6

Using balanced BST like AVL or Red-Black-Tree, we can easily maintain a set of values that:

  1. Insert/delete/query given value.
  2. Count the elements that smaller/larger than given value.
  3. Find the element with rank k after sort.

All above can be archived in O(log N) complexity.

My question is, is there any STL container supporting all 3 above operations in the same complexity?

I know STL set/multiset can be used for 1 and 2. And I examined the _Rb_tree based containers map/set/multiset, but none provides support for 3. Is there a way to subclassing ext/rb_tree to solve this?

mrflash818
  • 930
  • 13
  • 24
Terence Hang
  • 207
  • 1
  • 9

1 Answers1

1

The data structure you're looking for is an order statistic tree, which is a binary search tree where each node stores the size of the subtree rooted at that node.

This supports all of the listed operations in O(log n).

There exists an order statistic tree in GNU Policy-Based Data Structures (part of GNU C++).

The code would look something like this:

#include <iostream>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef
tree<
  int,
  null_type,
  less<int>,
  rb_tree_tag,
  tree_order_statistics_node_update>
set_t;

int main()
{
  set_t s;
  s.insert(12);
  s.insert(50);
  s.insert(30);
  s.insert(20);
  cout << "1st element: " << *s.find_by_order(1) << '\n';   // 20
  cout << "Position of 30: " << s.order_of_key(30) << '\n'; // 2
  return 0;
}

Live demo.

[Derived from this answer]

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138