Using balanced BST like AVL or Red-Black-Tree, we can easily maintain a set of values that:
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?
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.
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.
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);
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.
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 ...
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.
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
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With