Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ STL container suited for finding the nth element in dynamic ordered list?

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?

like image 646
Terence Hang Avatar asked Aug 25 '15 06:08

Terence Hang


People also ask

What does nth_ element do?

nth_element is a partial sorting algorithm that rearranges elements in [first, last) such that: The element pointed at by nth is changed to whatever element would occur in that position if [first, last) were sorted.

How do you find the nth element in a set?

Now, to access an element at nth index we need to create an iterator pointing to starting position and keep on increment the iterator till nth element is reached i.e. std::cout<<"3rd Element in set = "<<*setIt<<std::endl; std::set<std::string>::iterator setIt = setOfStr.

How do you find the nth element of a list in C++?

Accessing nth element in std::list using std::next() ForwardIterator next (ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1); template <class ForwardIterator> ForwardIterator next (ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1);

How does the nth element in a list sort the list?

It does not sort the list, just that all the elements, which precede the nth element are not greater than it, and all the elements which succeed it are not less than it.

What are containers in C++ STL (Standard Template Library)?

Containers in C++ STL (Standard Template Library) 1 array: Static contiguous array (class template) 2 vector: Dynamic contiguous array (class template) 3 deque: Double-ended queue (class template) 4 forward_list: Singly-linked list (class template) 5 list : Doubly-linked list (class template) More ...

What is nth_element in C++?

std::nth_element in C++ Difficulty Level : Hard Last Updated : 26 Jul, 2017 std::nth_element () is an STL algorithm which rearranges the list in such a way such that the element at the nth position is the one which should be at that position if we sort the list.

Why are the elements of a set container const?

As std::set members are const by definition, this container is not for me. See as well advantages of std::set vs vectors or maps as well as Using custom std::set comparator. @Igor If the user can modify the values, then they can make the container unsorted. That's why std::set 's elements are const


1 Answers

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]

like image 142
Bernhard Barker Avatar answered Oct 18 '22 16:10

Bernhard Barker