15 #ifndef PAAL_SPLAY_TREE_HPP
16 #define PAAL_SPLAY_TREE_HPP
18 #include <boost/utility.hpp>
19 #include <boost/iterator.hpp>
20 #include <boost/iterator/iterator_facade.hpp>
26 #include <unordered_map>
29 namespace data_structures {
38 template <
typename NPtr> std::size_t
node_size(
const NPtr &node) {
39 return !node ? 0 : node->size();
42 template <
typename V>
class Node;
55 return (!node) ?
nullptr : std::unique_ptr<Node<V>>(
new Node<V>(*node));
65 inline forward_tag other(reversed_tag) {
79 template <
typename V>
class Node {
82 using node_type = Node<value_type>;
83 using node_ptr = std::unique_ptr<node_type>;
86 explicit Node(
const value_type &val)
87 :
val_(val), parent_(nullptr), reversed_(false), size_(1) {}
92 parent_(nullptr), reversed_(n.reversed_), size_(n.size_) {
94 right_->parent_ =
this;
97 left_->parent_ =
this;
104 void set_parent(node_type *p) { parent_ = p; }
129 void set_right(node_ptr node) {
137 template <
typename Direction>
void set(node_ptr node, Direction dir_tag) {
147 template <
typename Direction>
149 if (node !=
nullptr) {
150 node->parent_ =
this;
152 child(dir_tag) = std::move(node);
160 node_ptr &child(forward_tag) {
return right(); }
162 template <
typename Direction> node_type *extreme(Direction dir_tag) {
163 node_type *node =
this;
165 while (node->child(dir_tag).get() !=
nullptr) {
166 node = node->child(dir_tag).get();
177 if (node !=
nullptr) {
178 return node->extreme(other(dir_tag));
185 if (node ==
nullptr) {
187 }
else if (node->child(other(dir_tag)).get() == last) {
207 std::size_t
size() {
return size_; }
215 std::swap(left_, right_);
216 if (left_ !=
nullptr) {
217 left_->subtree_reverse();
219 if (right_ !=
nullptr) {
220 right_->subtree_reverse();
229 if (node !=
nullptr) {
239 static const bool k_def_left = 0;
240 node_ptr left_, right_;
252 template <
typename V,
typename direction_tag = forward_tag>
254 :
public boost::iterator_facade<Iterator<V, direction_tag>, Node<V> *,
255 boost::bidirectional_traversal_tag, V &> {
260 using value_type = V;
264 Iterator() : current_(nullptr), rotation_cnt_(0), splay_(nullptr) {}
272 : current_(node), rotation_cnt_(0), splay_(splay) {}
279 : current_(other.current_), rotation_cnt_(0), splay_(other.splay_) {}
282 friend class boost::iterator_core_access;
295 current_ = current_->
advance(direction_tag{});
301 current_ = current_->
advance(other(direction_tag{}));
308 bool equal(
const Iterator &other)
const {
309 return this->current_ == other.current_;
313 value_type &dereference()
const {
return current_->
val_; }
317 std::size_t rotation_cnt_;
331 template <
typename T>
class splay_tree {
332 detail::forward_tag forward_tag;
333 detail::reversed_tag reversed_tag;
336 using value_type = T;
337 using node_type = detail::Node<value_type>;
338 using node_ptr =
typename node_type::node_ptr;
339 using iterator = detail::Iterator<value_type, detail::forward_tag>;
340 using const_iterator =
const iterator;
341 using reverse_iterator = detail::Iterator<value_type, detail::reversed_tag>;
342 using const_reverse_iterator =
const reverse_iterator;
344 splay_tree() =
default;
352 root_ = build_tree(b, e);
364 if (&splay ==
this)
return *
this;
366 *
this = std::move(sp);
374 for (; i != e; ++i) {
375 t_to_node_.insert(std::make_pair(*i, i.current_));
384 root_ = build_tree(std::begin(array), std::end(array));
389 return (root_ ==
nullptr)
391 :
iterator(root_->extreme(reversed_tag),
this);
399 return (root_ ==
nullptr)
408 std::size_t
size()
const {
return (root_ ==
nullptr) ? 0 : root_->size(); }
411 bool empty() {
return (root_ ==
nullptr); }
414 value_type &
operator[](std::size_t i)
const {
return find(i)->val_; }
419 if (node ==
nullptr) {
425 while (node != root_.get()) {
448 splay_internal(find(i));
490 root_->subtree_reverse();
498 explicit splay_tree(node_ptr root) : root_(std::move(root)) {}
500 template <
typename Direction>
501 splay_tree split(std::size_t i, Direction dir_tag) {
503 node_ptr new_root = std::move(root_->child(dir_tag));
504 if (new_root !=
nullptr) {
505 new_root->make_root();
507 if (root_ !=
nullptr) {
508 root_->update_size();
511 return splay_tree<value_type>(std::move(new_root));
514 iterator
splay(detail::forward_tag)
const {
515 return splay(root_->size() - 1);
518 iterator
splay(detail::reversed_tag)
const {
return splay(0); }
520 template <
typename Direction>
521 void merge(splay_tree other, Direction dir_tag) {
522 if (other.root_ ==
nullptr) {
526 assert(root_->child(dir_tag) ==
nullptr);
527 root_->set(std::move(other.root_), dir_tag);
531 node_ptr &get_parent(node_ptr &node)
const {
533 node_type *parent = node->parent();
534 assert(parent !=
nullptr);
535 node_type *granpa = parent->parent();
536 if (granpa ==
nullptr) {
539 if (granpa->left().get() == parent) {
540 return granpa->left();
542 assert(granpa->right().get() == parent);
543 return granpa->right();
552 void splay_internal(node_ptr &node)
const {
557 node_ptr &parent = get_parent(node);
558 if (parent == root_) {
559 if (node == parent->left()) {
560 rotate(root_, forward_tag);
562 assert(node == parent->right());
563 rotate(root_, reversed_tag);
566 node_ptr &grand = get_parent(parent);
567 if (node == parent->left() && parent == grand->left()) {
568 rotate(grand, forward_tag);
569 rotate(grand, forward_tag);
570 }
else if (node == parent->right() && parent == grand->right()) {
571 rotate(grand, reversed_tag);
572 rotate(grand, reversed_tag);
573 }
else if (node == parent->right() && parent == grand->left()) {
574 rotate(parent, reversed_tag);
575 rotate(grand, forward_tag);
576 }
else if (node == parent->left() && parent == grand->right()) {
577 rotate(parent, forward_tag);
578 rotate(grand, reversed_tag);
580 splay_internal(grand);
588 template <
typename Direction>
589 void rotate(node_ptr &parent, Direction dir_tag)
const {
590 auto other_tag = other(dir_tag);
591 node_ptr node = std::move(parent->child(other_tag));
593 parent->set_parent(node->parent());
594 node->set(std::move(parent->child(dir_tag)),
596 parent->set(std::move(node), dir_tag);
606 template <
typename I> node_ptr build_tree(
const I b,
const I e) {
610 std::size_t m = (e - b) / 2;
611 node_ptr node{
new node_type(*(b + m)) };
613 t_to_node_.insert(std::make_pair(*(b + m), node.get())).second;
615 node->set_left(build_tree(b, b + m));
616 node->set_right(build_tree(b + m + 1, e));
626 node_ptr &find(std::size_t i)
const {
627 node_ptr *node = &root_;
632 node_ptr *left = &((*node)->left());
633 std::size_t left_size =
node_size(*left);
634 if (left_size == i) {
636 }
else if (left_size > i) {
640 node = &(*node)->right();
646 std::size_t rotation_cnt_ = 0;
647 mutable node_ptr root_;
648 std::unordered_map<T, node_type *> t_to_node_;
653 #endif // PAAL_SPLAY_TREE_HPP
void update_size()
recomputes subtree size from sizes of children's subtrees
splay_tree split_higher(std::size_t i)
splits sequence, modified this contains elements {0, ..., i}
void merge_left(splay_tree other)
merges given tree to the left of the smallest element of this
std::unique_ptr< Node< V > > copy_node(std::unique_ptr< Node< V >> const &node)
copy node pointer
splay_tree(const I b, const I e)
constructs tree from elements between two iterators
void set_left(node_ptr node)
sets left child pointer
splay_tree(const splay_tree &splay)
constructor
std::size_t node_size(const NPtr &node)
void make_root()
detaches this node from parent
Iterator(const Iterator &other)
copy constructor
void merge_right(splay_tree other)
merges given tree to the right of the biggest element of this
void set(node_ptr node, Direction dir_tag)
sets child pointer
void normalize()
locally relaxes tree
void reverse(std::size_t i, std::size_t j)
reverses subsequence of elements with indices in {i, ..., j}
value_type & operator[](std::size_t i) const
reverse_iterator rbegin()
void subtree_reverse()
lazily reverses order in subtree
void normalize_root_path()
relaxes all nodes on path from root to this
Iterator()
iterator after last element
splay_tree & operator=(splay_tree &splay)
operator=
splay_tree & operator=(splay_tree &&splay)=default
operator=
void set_internal(node_ptr node, Direction dir_tag)
sets child pointer (no relaxation)
Iterator(node_ptr node, const ST *splay)
iterator to element in given node
std::size_t get_rotation_cnt() const
gets rotationCnt()
Node(const value_type &val)
iterator splay(std::size_t i) const
splays tree according to splay policy
splay_tree(const A &array)
creates tree from elements in std::vector
node_type * advance(Direction dir_tag)
value_type val_
value of the node
splay_tree split_lower(std::size_t i)
splits sequence, modified this contains elements {i, ...}
Node(const Node &n)
constructor
std::size_t get_idx(const T &t) const