/* Good performance for a splay tree depends on the fact that it is self-balancing, and indeed self optimizing,
* in that frequently accessed nodes will move nearer to the root where they can be accessed more quickly.
* This is an advantage for nearly all practical applications, and is particularly useful for implementing caches
* and garbage collection algorithms; however it is important to note that for uniform access, a splay tree's
* performance will be considerably (although not asymptotically) worse than a somewhat balanced simple
* binary search tree.
* Splay trees also have the advantage of being considerably simpler to implement than other self-balancing
* binary search trees, such as red-black trees or AVL trees, while their average-case performance is just
* as efficient. Also, splay trees do not need to store any bookkeeping data, thus minimizing memory requi-
* rements. However, these other data structures provide worst-case time guarantees, and can be more
* efficient in practice for uniform access.
*/
/* Author: 窦小蹦(fairyroad)
* Last update: June 03 09:00 EST 2010
* E-mail: [email protected]
*/
#ifndef SPLAYTREE_H_
#define SPLAYTREE_H_
#include<algorithm>
#include "memory.h" /*This file mainly contains some allocator classes
which are used for managing memory or somthing.*/
namespace SP_tree
{
template <class T>inline void swap(T& x, T& y)
{
T temp = x;
x = y;
y = temp;
};
template<class T, class U>struct pair
{
typedef T first_type;
typedef U second_type;
T first;
U second;
pair(const T& x = T(), const U& y = U()):first(x),second(y) {}
template<class V, class W>pair(const pair<V, W>& pr):first(pr.first),second(pr.second) {}
};
template <class T>struct less{
bool operator()(const T& x, const T& y) const { return x < y; } };
template <class T>struct greater{
bool operator()(const T& x, const T& y) const { return x > y; } };
}
using SP_tree::swap;
template <class Value>
struct Splaytree_node
{
typedef Splaytree_node* link_type;
Value data;
link_type parent, left, right;
Splaytree_node(const Value& _data = Value(), link_type p = 0, link_type l = 0,
link_type r = 0):
data(_data),parent(p),left(l),right(r) {}
Splaytree_node(const Splayree_node& _other):data(_other.data), parent(_other.parent),
left(_other.left), right(_other.right) {}
void swap_(Splaytree_node& rhs){
::swap(value,rhs.value);
::swap(parent,rhs.parent);
::swap(left,rhs.left);
::swap(right,rhs.right);
}
Splaytree_node& operator=(const Splaytree_node& x){
Splaytree_node tmp(x);
swap(tmp);
return *this;
}
virtual ~Splaytree_node() {}
static link_type minimum(link_type x){
while(x->left) x = x->left;
return x;
}
static link_type maximum(link_type x){
while(x->right) x = x->right;
return x;
}
};//end of Splaytree_node
template <class Value, class Ref, class Ptr>
class Splaytree_iterator
{
protected:
typename Splayree_node<Value>::link_type node;
public:
typedef Value value_type;
typedef Ref reference;
typedef Ptr pointer;
typedef Splaytree_iterator<Value,Value&,Value*> iterator;
typedef Splaytree_iterator<Value,const Value&,const Value*> const_iterator;
typedef Splayree_node<Value>* link_type;
typedef Splaytree_iterator<Value,Ref,Ptr> self;
typedef ::bidirectional_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
public:
void increment()//find the node
//whose key has the smallest value among all those whose key is bigger than the oringinal's
{
if(node->right)
{
node = node->right;
while(node->left) node = node->left;
}
else
{
link_type y = node->parent;
while(node == y->right)
{
node = y;
y = y->parent;
}
if(node->right != y) node = y;
}
}
void decrement()// find the node whose key has the biggest value among all those whose key is smaller than the oringinal's
{
if(node == node->parent->parent)
node = node->right;
else if(node->left)//if the node has a left-child,walk to the end in the right-hand direction
{
link_type y = node->left;
while(y->right) y = y->right;
node = y;
}
else//does not have a left-child,go up until find a node that doesn't belong to its father's left-child
{
link_type y = node->parent;
while(node == y->left)
{
node = y;
y = y->parent;
}
node = y;
}
}
Splaytree_iterator(link_type x = 0):node(x) {}
Splaytree_iterator(const Splaytree_iterator& it):node(it) {}
reference operator*()const { return node->data; }
pointer operator->()const { return &(operator*()); }
self& operator++()
{
increment();
return *this;
}
self operator++(int)
{
self tmp = *this;
increment();
return tmp;
}
self& operator--()
{
decrement();
return *this;
}
self operator--(int)
{
self tmp = *this;
decrement();
return tmp;
}
private:
friend bool operator==(const Splaytree_iterator& x, const Splaytree_iterator& y) {return x.node == y.node; }
friend bool operator!=(const Splaytree_iterator& x, const Splaytree_iterator& y) {return x.node != y.node; }
};
//end of Splaytree_iterator
template <class Key, class Value, class KeyOfValue, class Compare = less<Key>, class Alloc = allocator<Value> >
class Splaytree //Splay Tree
{
public:
typedef Key key_type;
typedef Value value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename Splaytree_node<Value>::link_type link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef typename Splaytree_node<value_type, reference, pointer>::iterator iterator;
typedef typename Splaytree_node<value_type, const_reference, const_pointer>::const_iterator const_iterator;
typedef ::reverse_iterator<iterator> reverse_iterator;
typedef ::reverse_iterator<const_iterator> const_reverse_iterator;
private:
typedef typename Alloc::template rebind<Splaytree_node<Value> >::other allocator_type;
allocator_type alloc;
void release_node(link_type p)
{
alloc.destroy(p);//These two functions are defined in the memory.hpp file.
alloc.deallocate(p, 0);//And their functions can be easily implied from their names.
}
//creat a node
link_type get_node(const Value& _data = Value(), link_type p = 0, link_type l = 0, link_type r = 0)
{
link_type ptr = 0;
try{
ptr = alloc.allocate(sizeof(Splaytree_node<Value>));
//This function is defined in the memory.hpp file.
alloc.construct(ptr, Splaytree_node<Value>(_data, p, l, r));//This function is defined in the memory.hpp file.
}
catch(){
release_node(ptr);
throw;
}
return ptr;
}
link_type clone_node(link_type x) { return get_node(x->data, x->parent, x->left, x->right); }//copy a node
void init()
{
header = get_node();
root() = 0;
leftmost() = header;
rightmost() = header;
}
protected:
// The member data of Splaytree
size_type node_count;//records the amount of nodes in the tree
link_type header;//an accessorial data used for complemention
Compare key_compare;
// These three functions are used for expediently getting the member of the head node.
link_type& root() const { return header->parent; }
link_type& leftmost() const { return header->left; }
link_type& rightmost()const { return header->right; }
// These five functions are used for expediently getting the member of node x.
static link_type& left(link_type x) {return x->left; }
static link_type& right(link_type x) { return x->right; }
static link_type& parent(link_type x) { return x->parent; }
static reference value(link_type x) { return x->data; }
static const Key& key(link_type x) { return KeyOfValue()(value(x)); }
public:
explicit Splaytree(const Compare& comp = Compare()) : node_count(0), key_compare(comp) { init(); }
Splaytree(const Splaytree& x):node_count(0), key_compare(x.key_compare)
{
header = get_node();
if(0 == x.root())
{
root() = 0;
leftmost() = header;
rightmost() = header;
}
else
{
try{ root() = _copy(x.root(), header); }
catch()
{
release_node(header);
throw;
}
leftmost() = minimum(root());
rightmost() = maximum(root());
}
node_count = x.node_count;
}
virtual ~Splaytree()
{
clear();
release_node(header);
}
Splaytree& operator=(const Splaytree& x);
public:
const Compare& key_comp() const { return key_compare; }
const allocator_type& get_allocator() const { return alloc; }
iterator begin() { return leftmost(); }
const_iterator begin() const { return leftmost(); }
iterator end() { return header; }
const_iterator end() const { return header; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
bool empty() const { return 0 == node_count; }
size_type size() const { return node_count; }
bool find(const value_type& x) const;
const_reference findmax() const;
const_reference findmin() const;
iterator insert(const value_type& x);
void remove(const Value& x);
void remove(iterator position);
void remove(iterator first, iterator last);
void MakeEmpty();
friend bool operator==(const Splaytree& x, const Splaytree& y)
{
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
friend bool operator<(const Splaytree_tree& x, const Splaytree_tree& y)
{
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
void swap(Splaytree& t)
{
::swap(header, t.header);
::swap(node_count, t.node_count);
::swap(key_compare, t.key_compare);
}
void clear()
{
if(node_count != 0)
{
erase(root());
leftmost() = header;
root() = 0;
rightmost() = header;
node_count = 0;
}
}
}; //end of Splaytree
//Next are definitions of some indispensable functions
template <class Value>
inline void _rotate_left(Splaytree_node<Value>* x, Splaytree_node<Value>*& root)
{
Splaytree_node<Value>* y = x->right;
x->right = y->left;
if(y->left) y->left->parent = x;
y->parent = x->parent;
if(x == root) root = y;
else if(x == x->parent->left) x->parent->left = y;
else x->parent->right = y;
y->left = x;
x->parent = y;
}
template <class Value>
inline void _rotate_right(Splaytree_node<Value>* x, Splaytree_node<Value>*& root)
{
Splaytree_node<Value>* y = x->left;
x->left = y->right;
if(y->right) y->right->parent = x;
y->parent = x->parent;
if(x == root) root = y;
else if(x == x->parent->right) x->parent->right = y;
else x->parent->left = y;
y->right = x;
x->parent = y;
}
template <class Key, class Value, class KeyOfValue, class Compare = less<Key>, class Alloc = allocator<Value> >
inline void _splay(const Vaule& x,Splaytree_node<Value>*& root) //The variable root represents the root, not header, of a tree.
{
if( root == NULL) return;
Splaytree_node* header = root->parent;//this variable "header" is the accurate header of the tree
Splaytree_node* leftTreeMax;
Splaytree_node* rightTreeMin;
static Splaytree_node __header(x);//this variable "__header" is an acessorial member
__header.left = __header.right = NULL;
leftTreeMax = rightTreeMin = &__header;
while(true)
{
if(key_compare( KeyOfValue()(x),key(root))){
if(key_compare(KeyOfValue()(x), key(root->left))){
_rotate_left(root,root());
}
if(root->left == NULL) break;
rightTreeMin->left = root;
rightTreeMin = root;
root = root->left;
}
else if(key_compare(key(root)),KeyOfValue()(x)){
if(key_compare(key(root->right)), KeyOfValue()(x)){
_rotate_right(root,root());
}
if(root->right == NULL) break;
leftTreeMax->right = root;
leftTreeMax = root;
root = root->right;
}
else break;
}
leftTreeMin->right = root->left;
rightTreeMax->left = root->right;
root->left = __header.right;
root->right = __header.left;
root->parent = header;
header->left = root->minimum(root->left); //leftmost()
header->right = root->maximum( root->right); //rightmost()
}
//Next are definitions of some member functions
//operator=()
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
Splaytree<Key, Value, KeyOfValue, Compare, Alloc>& Splaytree<Key, Value, KeyOfValue, Compare, Alloc>::operator=(const Splaytree<Key, Value, KeyOfValue, Compare, Alloc>& x)
{
if(this != &x)
{
clear();
node_count = 0;
key_compare = x.key_compare;
if(x.root()==NULL){
root() = NULL;
leftmost() = header;
rightmost() = header;
}
else{
root() = clone_node(x.root());
leftmost() = Splayree_node<Value>::minimum(root());
rightmost() = Splayree_node<Value>::maximum(root());
node_count = x.node_count;
}
}
return *this;
}
template<class Key,class Value,class KeyOfValue,class compare,class Alloc>
bool Splaytree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Value& x)
{
_splay(x,root());
return (value(root()) == x)?true:false;
}
template<class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename Splaytree<Key, Value, KeyOfValue, Compare, Alloc>::const_reference findmax()
{
Splaytree_node tmp = *this;
if(!tmp) return NULL;
tmp = maximum(tmp);
value_type v = tmp.data;
_splay(v,root());
return v;
}
template<class Key, class Value, class KeyOfValue, class Compare, class Alloc>
typename Splaytree<Key, Value, KeyOfValue, Compare, Alloc>::const_reference findmin()
{
Splaytree_node tmp = *this;
if(!tmp) return NULL;
tmp = minimum(tmp);
value_type v = tmp.data;
_splay(v,root());
return v;
}
template<class Key, class Value, class KeyOfValue, class Compare, class Alloc>
void Splaytree<Key, Value, KeyOfValue, Compare, Alloc>::insert(const Value& x)
{
Splaytree_node tmp(x);
if(root()==NULL){
tmp->left = tmp->right = NULL;
tmp->parent = header;
header->parent = tmp;
}
else{
_splay(x,root());
if(key_compare( KeyOfValue()(x),key(root()))){
tmp->left = root()->left;
tmp->right = root();
root()->left = NULL;
tmp->parent = header;
header->parent = tmp;
leftmost() = Splayree_node<Value>::minimum(root());
rightmost() = Splayree_node<Value>::maximum(root());
}
else if(key_compare( key(root())),KeyOfValue()(x)){
tmp->right = root()->right;
tmp->left = root();
root()->right = NULL;
tmp->parent = header;
header->parent = tmp;
leftmost() = Splayree_node<Value>::minimum(root());
rightmost() = Splayree_node<Value>::maximum(root());
}
else return;
}
++node_count;
}
template<class Key,class Value,class KeyOfValue,class compare,class Alloc>
void Splaytree<Key, Value, KeyOfValue, Compare, Alloc>::remove(const Value& x)
{
_splay(x,root());
if(KeyOfValue()(x) != key(root())) return;
Splaytree_node tmp;
if(root()->left == NULL) tmp = root()->right;
else{
tmp = root()->left;
_splay(x,tmp);
tmp->right = root()->right;
}
release_node(root());
root() = tmp;
header->parent = tmp;
leftmost() = Splayree_node<Value>::minimum(root());
rightmost() = Splayree_node<Value>::maximum(root());
--node_count;
}
template<class Key,class Value,class KeyOfValue,class compare,class Alloc>
void Splaytree<Key, Value, KeyOfValue, Compare, Alloc>::remove(iterator position) { remove(*position);}
template<class Key,class Value,class KeyOfValue,class compare,class Alloc>
void Splaytree<Key, Value, KeyOfValue, Compare, Alloc>::remove(iterator first,iterator last)
{
for(const_iterator pos = first;pos!=last;++pos) remove(pos);
}
template<class Key,class Value,class KeyOfValue,class compare,class Alloc>
void Splaytree<Key, Value, KeyOfValue, Compare, Alloc>::MakeEmpty()
{
while(!empty()){
const_reference v = findmax();
remove(v);
}
}
#endif // SPLAYTREE_H_