3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 18:31:49 +00:00
z3/lib/splay_tree.h
Leonardo de Moura e9eab22e5c Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2012-10-02 11:35:25 -07:00

181 lines
4.7 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
splay_tree.h
Abstract:
Splay trees
Author:
Leonardo de Moura (leonardo) 2008-01-31.
Revision History:
--*/
#ifndef _SPLAY_TREE_H_
#define _SPLAY_TREE_H_
#include"util.h"
#include"buffer.h"
template<typename Key, typename Compare>
class splay_tree : private Compare {
struct cell {
Key m_key;
cell * m_left;
cell * m_right;
cell():m_left(0), m_right(0) {}
cell(Key const & k, cell * l = 0, cell * r = 0):
m_key(k), m_left(l), m_right(r) {}
};
cell * m_root;
int compare(Key const & k1, Key const & k2) const { return Compare::operator()(k1, k2); }
cell * splay(cell * c, Key const & k);
void display_core(std::ostream & out, cell * c) const {
if (c) {
out << "(" << c->m_key << " ";
display_core(out, c->m_left);
out << " ";
display_core(out, c->m_right);
out << ")";
}
else
out << "null";
}
public:
splay_tree(Compare const & c = Compare()):
Compare(c),
m_root(0) {}
~splay_tree() {
m_root = 0;
}
void insert(Key const & k);
bool find(Key const & k, Key & r) const;
void erase(Key const & k);
void reset();
bool empty() const { return m_root == 0; }
bool singleton() const { return m_root != 0 && m_root->m_left == 0 && m_root->m_right == 0; }
/**
\brief Visit nodes in the splay tree in ascending order.
The Visitor functor should provide the following methods:
- bool visit_left(Key const & k)
return true if the left child should be visited
- bool visit_right(Key const & k)
return true if the right child should be visited
- void operator()(Key const & k)
do something with the key.
*/
template<typename Visitor>
void visit_core(Visitor & v) {
typedef std::pair<cell *, bool> entry;
if (m_root) {
buffer<entry> todo;
todo.push_back(entry(m_root, false));
while (!todo.empty()) {
entry & curr = todo.back();
cell * c = curr.first;
if (!curr.second) {
curr.second = true;
if (c->m_left && v.visit_left(c->m_key))
todo.push_back(entry(c->m_left, false));
}
else {
v(c->m_key);
todo.pop_back();
if (c->m_right && v.visit_right(c->m_key))
todo.push_back(entry(c->m_right, false));
}
}
}
}
template<typename Visitor>
struct all_visitor_wrapper {
Visitor & m_visitor;
all_visitor_wrapper(Visitor & v):m_visitor(v) {}
bool visit_right(Key const & k) { return true; }
bool visit_left(Key const & k) { return true; }
void operator()(Key const & k) { m_visitor.operator()(k); }
};
/**
\brief Visit all nodes in the splay tree in ascending order.
- void operator()(Key const & k)
do something with the key pair.
*/
template<typename Visitor>
void visit(Visitor & v) {
all_visitor_wrapper<Visitor> w(v);
visit_core(w);
}
template<typename Visitor, bool LE>
struct visitor_wrapper {
Visitor & m_visitor;
splay_tree & m_tree;
Key m_key;
visitor_wrapper(Visitor & v, splay_tree & t, Key const & k):m_visitor(v), m_tree(t), m_key(k) {}
bool visit_left(Key const & k) {
return LE || m_tree.compare(k, m_key) > 0;
}
bool visit_right(Key const & k) {
return !LE || m_tree.compare(k, m_key) < 0;
}
void operator()(Key const & k) {
if ((LE && m_tree.compare(k, m_key) <= 0) ||
(!LE && m_tree.compare(k, m_key) >= 0))
m_visitor.operator()(k);
}
};
/**
\brief Visit all nodes with keys less than or equal to k.
- void operator()(Key const & k)
do something with the key.
*/
template<typename Visitor>
void visit_le(Visitor & v, Key const & k) {
visitor_wrapper<Visitor, true> w(v, *this, k);
visit_core(w);
}
/**
\brief Visit all nodes with keys greater than or equal to k.
- void operator()(Key const & k)
do something with the key.
*/
template<typename Visitor>
void visit_ge(Visitor & v, Key const & k) {
visitor_wrapper<Visitor, false> w(v, *this, k);
visit_core(w);
}
void display(std::ostream & out) const {
display_core(out, m_root);
}
};
#endif