#ifndef ITREE_H_
#define ITREE_H_
#include <vector>
#include <set>
#include <assert.h>
#include <algorithm>
#include <iterator>
template<class T, class A = std::allocator<T> > class itree
{
public:
typedef T invl_type;
typedef T::range_type range_type;
typedef std::vector<invl_type, A> invl_vec;
typedef invl_vec::iterator iterator;
typedef invl_vec::const_iterator const_iterator;
// other types derived from invl_vec omitted
...
private:
typedef struct node_tag // Interval tree nodes
{
range_type discrim; // discriminant
int start; // starting offset in AL and DH
int size; // number of entris in AL and DH
struct node_tag *left; // left subtree
struct node_tag *right; // right subtree
} node;
public:
... // query iterator definition omitted
... // functions forwarded to std::vector omitted
// Interval tree specific functionality follows
itree() : root(NULL) {}
~itree() { deconstruct(); }
void deconstruct(void) // reverts initialization mode
{ delete_tree(root); root = NULL; }
void delete_tree(node *cur_node) { // delete nodes in tree
if (cur_node != NULL) {
delete_tree(cur_node->left); // left tree
// recursively
delete_tree(cur_node->right); // right tree
// recursively
delete cur_node;
}
}
bool constructed() const { return root != NULL; }
// build the interval tree structure and
// put the container into query mode
itree const& construct(void) {
std::vector<range_type> values;
std::vector<bool> flags(invls.size(), false);
int num_al_dh = 0;
extract_values(values);
al.resize(invls.size());
dh.resize(invls.size());
root = construct_tree(values, flags, num_al_dh, 0,
values.size() - 1);
return *this;
}
... // extract_values function definition omitted
// recursively construct the tree
node*
construct_tree(const std::vector<range_type>& values,
std::vector<bool>& flags, int& num_al_dh,
int start, int end) {
int discrim_pos;
range_type discrim;
int list_start, list_size;
node *root, *left, *right;
bool continue_left = false;
bool continue_right = false;
root = left = right = NULL;
if (start > end)
return root;
discrim_pos = (start + end) / 2;
discrim = values[discrim_pos];
list_start = num_al_dh;
list_size = 0;
for (int i = 0; i < invls.size(); i++) {
if (flags[i])
continue;
if ((invls[i].low() <= discrim) &&
(invls[i].high() >= discrim)) {
al[num_al_dh] = &(invls[i]);
dh[num_al_dh] = &(invls[i]);
num_al_dh++;
list_size++;
flags[i] = true;
}
if ((invls[i].low() < discrim) &&
(invls[i].high() < discrim))
continue_left = true;
if ((invls[i].low() > discrim) &&
(invls[i].high() > discrim))
continue_right = true;
}
// see if left and/or right subtree needs to be built
if (continue_left && (start <= (discrim_pos - 1)))
left = construct_tree(values, flags, num_al_dh, start,
discrim_pos - 1);
if (continue_right && ((discrim_pos + 1) <= end))
right = construct_tree(values, flags, num_al_dh,
discrim_pos + 1, end);
// this node is needed only if thre are entries in the
// AL/DH list or the left or right subtree exists.
if ((list_size > 0) || (left != NULL) || (right != NULL)) {
std::sort(&(al[list_start]),
&(al[list_start + list_size]), comp_for_al);
std::sort(&(dh[list_start]),
&(dh[list_start + list_size]), comp_for_dh);
root = new node;
root->left = left;
root->right = right;
root->discrim = discrim;
root->start = list_start;
root->size = list_size;
}
return root;
}
... // comparison functions for sorting AL and DL omitted
query_iterator qbegin(range_type x) {
assert(constructed());
query_iterator it(root, 0, x, &al, &dh);
it.init_node(); return it;
}
query_iterator qend(range_type x) {
assert(constructed());
query_iterator it(NULL, 0, x, NULL, NULL);
return it;
}
private:
invl_vec invls; // vector of intervals
std::vector<invl_type*> al, dh; // vectors of interval ptrs
node *root; // Interval tree root node
};
#endif // ITREE_H_