32 #ifndef __FASTJET_SEARCHTREE_HH__ 
   33 #define __FASTJET_SEARCHTREE_HH__ 
   38 #include "fastjet/internal/base.hh" 
   40 FASTJET_BEGIN_NAMESPACE      
 
   54 template<
class T> 
class SearchTree {
 
   59   class const_circulator;
 
   62   SearchTree(
const std::vector<T> & init);
 
   66   SearchTree(
const std::vector<T> & init, 
unsigned int max_size);
 
   69   void remove(
unsigned node_index);
 
   70   void remove(
typename SearchTree::Node * node);
 
   71   void remove(
typename SearchTree::circulator & circ);
 
   76   circulator insert(
const T & value);
 
   78   const Node & operator[](
int i)
 const {
return _nodes[i];};
 
   81   unsigned int size()
 const {
return _nodes.size() - _available_nodes.size();}
 
   84   void verify_structure();
 
   85   void verify_structure_linear() 
const;
 
   86   void verify_structure_recursive(
const Node * , 
const Node * , 
const Node * ) 
const;
 
   89   void print_elements();
 
   93 #ifdef __FASTJET_SEARCHTREE_TRACK_DEPTH 
   95   inline unsigned int max_depth()
 const {
return _max_depth;};
 
   97   inline unsigned int max_depth()
 const {
return 0;};
 
  100   int loc(
const Node * node) 
const ;
 
  103   Node * _find_predecessor(
const Node *);
 
  105   Node * _find_successor(
const Node *);
 
  107   const Node & operator[](
unsigned int i)
 const {
return _nodes[i];};
 
  111   const_circulator somewhere() 
const;
 
  112   circulator somewhere();
 
  116   void _initialize(
const std::vector<T> & init);
 
  118   std::vector<Node> _nodes;
 
  119   std::vector<Node *> _available_nodes;
 
  121   unsigned int _n_removes;
 
  128   void _do_initial_connections(
unsigned int this_one, 
unsigned int scale,
 
  129                                unsigned int left_edge, 
unsigned int right_edge,
 
  133 #ifdef __FASTJET_SEARCHTREE_TRACK_DEPTH 
  134   unsigned int _max_depth;
 
  146 template<
class T> 
class SearchTree<T>::Node{
 
  152   bool treelinks_null()
 const {
 
  153     return ((parent==0) && (left==0) && (right==0));};
 
  156   inline void nullify_treelinks() {
 
  164   void reset_parents_link_to_me(Node * XX);
 
  175 template<
class T> 
void SearchTree<T>::Node::reset_parents_link_to_me(
typename SearchTree<T>::Node * XX) {
 
  176   if (parent == NULL) {
return;}
 
  177   if (parent->right == 
this) {parent->right = XX;}
 
  178   else {parent->left = XX;}
 
  189 template<
class T> 
class SearchTree<T>::circulator{
 
  199   friend class SearchTree<T>::const_circulator;
 
  200   friend class SearchTree<T>;
 
  202   circulator() : _node(NULL) {}
 
  204   circulator(Node * node) : _node(node) {}
 
  206   const T * operator->()
 const {
return &(_node->value);}
 
  207   T * operator->() {
return &(_node->value);}
 
  208   const T & 
operator*()
 const {
return _node->value;}
 
  212   circulator & operator++() {
 
  213     _node = _node->successor; 
 
  218   circulator operator++(
int) {
 
  219     circulator tmp = *
this;
 
  220     _node = _node->successor; 
 
  224   circulator & operator--() {
 
  225     _node = _node->predecessor; 
 
  230   circulator operator--(
int) {
 
  231     circulator tmp = *
this;
 
  232     _node = _node->predecessor; 
 
  236   circulator next()
 const {
 
  237     return circulator(_node->successor);}
 
  240   circulator previous()
 const {
 
  241     return circulator(_node->predecessor);}
 
  243   bool operator!=(
const circulator & other)
 const {
return other._node != _node;}
 
  244   bool operator==(
const circulator & other)
 const {
return other._node == _node;}
 
  257 template<
class T> 
class SearchTree<T>::const_circulator{
 
  260   const_circulator() : _node(NULL) {}
 
  262   const_circulator(
const Node * node) : _node(node) {}
 
  263   const_circulator(
const circulator & circ) :_node(circ._node) {}
 
  265   const T * operator->() {
return &(_node->value);}
 
  266   const T & 
operator*()
 const {
return _node->value;}
 
  269   const_circulator & operator++() {
 
  270     _node = _node->successor; 
 
  275   const_circulator operator++(
int) {
 
  276     const_circulator tmp = *
this;
 
  277     _node = _node->successor; 
 
  282   const_circulator & operator--() {
 
  283     _node = _node->predecessor; 
 
  288   const_circulator operator--(
int) {
 
  289     const_circulator tmp = *
this;
 
  290     _node = _node->predecessor; 
 
  294   const_circulator next()
 const {
 
  295     return const_circulator(_node->successor);}
 
  298   const_circulator previous()
 const {
 
  299     return const_circulator(_node->predecessor);}
 
  303   bool operator!=(
const const_circulator & other)
 const {
return other._node != _node;}
 
  304   bool operator==(
const const_circulator & other)
 const {
return other._node == _node;}
 
  316 template<
class T> SearchTree<T>::SearchTree(
const std::vector<T> & init,
 
  317                                             unsigned int max_size) :
 
  320   _available_nodes.reserve(max_size);
 
  321   _available_nodes.resize(max_size - init.size());
 
  322   for (
unsigned int i = init.size(); i < max_size; i++) {
 
  323     _available_nodes[i-init.size()] = &(_nodes[i]);
 
  331 template<
class T> SearchTree<T>::SearchTree(
const std::vector<T> & init) :
 
  332   _nodes(init.size()), _available_nodes(0) {
 
  335   _available_nodes.reserve(init.size());
 
  341 template<
class T> 
void SearchTree<T>::_initialize(
const std::vector<T> & init) {
 
  344   unsigned n = init.size();
 
  350 #ifdef __FASTJET_SEARCHTREE_TRACK_DEPTH 
  356   for (
unsigned int i = 1; i<n; i++) {
 
  357     assert(!(init[i] < init[i-1]));
 
  361   for(
unsigned int i = 0; i < n; i++) {
 
  362     _nodes[i].value = init[i];
 
  363     _nodes[i].predecessor = (& (_nodes[i])) - 1;
 
  364     _nodes[i].successor   = (& (_nodes[i])) + 1;
 
  365     _nodes[i].nullify_treelinks();
 
  368   _nodes[0].predecessor = (& (_nodes[n-1]));
 
  369   _nodes[n-1].successor = (& (_nodes[0]));
 
  372   unsigned int scale = (n+1)/2;
 
  373   unsigned int top   = std::min(n-1,scale);
 
  374   _nodes[top].parent = NULL;
 
  375   _top_node = &(_nodes[top]);
 
  376   _do_initial_connections(top, scale, 0, n, 0);
 
  385 template<
class T> 
inline  int SearchTree<T>::loc(
const Node * node)
 const {
return node == NULL? 
 
  386       -999 : node - &(_nodes[0]);}
 
  392 template<
class T> 
void SearchTree<T>::_do_initial_connections(
 
  393                                          unsigned int this_one, 
 
  395                                          unsigned int left_edge,
 
  396                                          unsigned int right_edge,
 
  400 #ifdef __FASTJET_SEARCHTREE_TRACK_DEPTH 
  402   _max_depth = max(depth, _max_depth);
 
  406   unsigned int ref_new_scale = (scale+1)/2;
 
  409   unsigned new_scale = ref_new_scale;
 
  410   bool     did_child  = 
false;
 
  412     int left = this_one - new_scale; 
 
  414     if (left >= static_cast<int>(left_edge) 
 
  415                         && _nodes[left].treelinks_null() ) {
 
  416       _nodes[left].parent = &(_nodes[this_one]);
 
  417       _nodes[this_one].left = &(_nodes[left]);
 
  419       _do_initial_connections(left, new_scale, left_edge, this_one, depth+1);
 
  424     unsigned int old_new_scale = new_scale;
 
  425     new_scale = (old_new_scale + 1)/2;
 
  427     if (new_scale == old_new_scale) 
break;
 
  429   if (!did_child) {_nodes[this_one].left = NULL;}
 
  433   new_scale = ref_new_scale;
 
  436     unsigned int right = this_one + new_scale;
 
  437     if (right < right_edge  && _nodes[right].treelinks_null()) {
 
  438       _nodes[right].parent = &(_nodes[this_one]);
 
  439       _nodes[this_one].right = &(_nodes[right]);
 
  441       _do_initial_connections(right, new_scale, this_one+1,right_edge,depth+1);
 
  446     unsigned int old_new_scale = new_scale;
 
  447     new_scale = (old_new_scale + 1)/2;
 
  449     if (new_scale == old_new_scale) 
break;
 
  451   if (!did_child) {_nodes[this_one].right = NULL;}
 
  458 template<
class T> 
void SearchTree<T>::remove(
unsigned int node_index) {
 
  459   remove(&(_nodes[node_index]));
 
  463 template<
class T> 
void SearchTree<T>::remove(circulator & circ) {
 
  470 template<
class T> 
void SearchTree<T>::remove(
typename SearchTree<T>::Node * node) {
 
  475   assert(!node->treelinks_null());
 
  478   node->predecessor->successor = node->successor;
 
  479   node->successor->predecessor = node->predecessor;
 
  481   if (node->left == NULL && node->right == NULL) {
 
  484     node->reset_parents_link_to_me(NULL); 
 
  486   } 
else if (node->left != NULL && node->right == NULL){
 
  488     node->reset_parents_link_to_me(node->left);
 
  490     node->left->parent = node->parent;         
 
  492     if (_top_node == node) {_top_node = node->left;}
 
  494   } 
else if (node->left == NULL && node->right != NULL){
 
  496     node->reset_parents_link_to_me(node->right);
 
  498     node->right->parent = node->parent;   
 
  500     if (_top_node == node) {_top_node = node->right;}
 
  507     bool use_predecessor = (_n_removes % 2 == 1);
 
  508     if (use_predecessor) {
 
  511       replacement = node->predecessor;
 
  512       assert(replacement->right == NULL); 
 
  515       if (replacement != node->left) {
 
  516         if (replacement->left != NULL) {
 
  517           replacement->left->parent = replacement->parent;}
 
  518         replacement->reset_parents_link_to_me(replacement->left);
 
  519         replacement->left   = node->left;
 
  521       replacement->parent = node->parent;
 
  522       replacement->right  = node->right;
 
  526       replacement = node->successor;
 
  527       assert(replacement->left == NULL); 
 
  528       if (replacement != node->right) {
 
  529         if (replacement->right != NULL) {
 
  530           replacement->right->parent = replacement->parent;}
 
  531         replacement->reset_parents_link_to_me(replacement->right);
 
  532         replacement->right  = node->right;
 
  534       replacement->parent = node->parent;
 
  535       replacement->left   = node->left;
 
  537     node->reset_parents_link_to_me(replacement);
 
  540     if (node->left  != replacement) {node->left->parent  = replacement;}
 
  541     if (node->right != replacement) {node->right->parent = replacement;}
 
  544     if (_top_node == node) {_top_node = replacement;}
 
  548   node->nullify_treelinks();
 
  549   node->predecessor = NULL;
 
  550   node->successor   = NULL;
 
  555   _available_nodes.push_back(node);
 
  563 template<
class T> 
typename SearchTree<T>::circulator SearchTree<T>::insert(
const T & value) {
 
  565   assert(_available_nodes.size() > 0);
 
  567   Node * node = _available_nodes.back();
 
  568   _available_nodes.pop_back();
 
  571   Node * location = _top_node;
 
  572   Node * old_location = NULL;
 
  575 #ifdef __FASTJET_SEARCHTREE_TRACK_DEPTH 
  576   unsigned int depth = 0;
 
  578   while(location != NULL) {
 
  579 #ifdef __FASTJET_SEARCHTREE_TRACK_DEPTH 
  582     old_location = location;
 
  583     on_left = value < location->value;
 
  584     if (on_left) {location = location->left;}
 
  585     else {location = location->right;}
 
  587 #ifdef __FASTJET_SEARCHTREE_TRACK_DEPTH 
  588   _max_depth = max(depth, _max_depth);
 
  591   node->parent = old_location;
 
  592   if (on_left) {node->parent->left = node;} 
 
  593   else {node->parent->right = node;}
 
  597   node->predecessor = _find_predecessor(node);
 
  598   if (node->predecessor != NULL) {
 
  601     node->successor = node->predecessor->successor;
 
  602     node->predecessor->successor = node;
 
  603     node->successor->predecessor = node;
 
  607     node->successor = _find_successor(node);
 
  608     assert(node->successor != NULL); 
 
  610     node->predecessor = node->successor->predecessor;
 
  611     node->successor->predecessor = node;
 
  612     node->predecessor->successor = node;
 
  615   return circulator(node);
 
  620 template<
class T> 
void SearchTree<T>::verify_structure() {
 
  623   verify_structure_linear();
 
  628   const Node * left_limit = _top_node;
 
  629   while (left_limit->left != NULL) {left_limit = left_limit->left;}
 
  630   const Node * right_limit = _top_node;
 
  631   while (right_limit->right != NULL) {right_limit = right_limit->right;}
 
  634   verify_structure_recursive(_top_node, left_limit, right_limit);
 
  639 template<
class T> 
void SearchTree<T>::verify_structure_recursive(
 
  640                       const typename SearchTree<T>::Node * element, 
 
  641                       const typename SearchTree<T>::Node * left_limit,
 
  642                       const typename SearchTree<T>::Node * right_limit)
  const {
 
  644   assert(!(element->value < left_limit->value));
 
  645   assert(!(right_limit->value < element->value));
 
  647   const Node * left = element->left;
 
  649     assert(!(element->value < left->value));
 
  650     if (left != left_limit) {
 
  652       verify_structure_recursive(left, left_limit, element);}
 
  655   const Node * right = element->right;
 
  657     assert(!(right->value < element->value));
 
  658     if (right != right_limit) {
 
  660       verify_structure_recursive(right, element, right_limit);}
 
  665 template<
class T> 
void SearchTree<T>::verify_structure_linear()
 const {
 
  671   for(
unsigned i = 0; i < _nodes.size(); i++) {
 
  672     const typename SearchTree<T>::Node * node = &(_nodes[i]);
 
  674     if (node->treelinks_null()) {n_null++; 
continue;}
 
  677     if (node->parent == NULL) {
 
  684       assert((node->parent->left == node) ^ (node->parent->right == node));
 
  690     if (node->left != NULL) {
 
  691       assert(!(node->value < node->left->value ));}
 
  694     if (node->right != NULL) {
 
  695       assert(!(node->right->value < node->value ));}
 
  698   assert(n_top == 1 || (n_top == 0 && size() <= 1) );
 
  699   assert(n_null == _available_nodes.size() ||
 
  700          (n_null == _available_nodes.size() + 1 && size() == 1));
 
  705 template<
class T> 
typename SearchTree<T>::Node * SearchTree<T>::_find_predecessor(
const typename SearchTree<T>::Node * node) {
 
  707   typename SearchTree<T>::Node * newnode;
 
  708   if (node->left != NULL) {
 
  710     newnode = node->left;
 
  711     while(newnode->right != NULL) {newnode = newnode->right;}
 
  714     const typename SearchTree<T>::Node * lastnode = node;
 
  715     newnode = node->parent;
 
  718     while(newnode != NULL) {
 
  719       if (newnode->right == lastnode) {
return newnode;}
 
  721       newnode = newnode->parent;
 
  729 template<
class T> 
typename SearchTree<T>::Node * SearchTree<T>::_find_successor(
const typename SearchTree<T>::Node * node) {
 
  731   typename SearchTree<T>::Node * newnode;
 
  732   if (node->right != NULL) {
 
  734     newnode = node->right;
 
  735     while(newnode->left != NULL) {newnode = newnode->left;}
 
  738     const typename SearchTree<T>::Node * lastnode = node;
 
  739     newnode = node->parent;
 
  742     while(newnode != NULL) {
 
  743       if (newnode->left == lastnode) {
return newnode;}
 
  745       newnode = newnode->parent;
 
  754 template<
class T> 
void SearchTree<T>::print_elements() {
 
  755   typename SearchTree<T>::Node * base_node = &(_nodes[0]);
 
  756   typename SearchTree<T>::Node * node = base_node;
 
  758   int n = _nodes.size();
 
  759   for(; node - base_node < n ; node++) {
 
  760     printf(
"%4d parent:%4d left:%4d right:%4d pred:%4d succ:%4d value:%10.6f\n",loc(node), loc(node->parent), loc(node->left), loc(node->right), loc(node->predecessor),loc(node->successor),node->value);
 
  765 template<
class T> 
typename SearchTree<T>::circulator SearchTree<T>::somewhere() {
 
  766   return circulator(_top_node);
 
  771 template<
class T> 
typename SearchTree<T>::const_circulator SearchTree<T>::somewhere()
 const {
 
  772   return const_circulator(_top_node);
 
  776 FASTJET_END_NAMESPACE
 
  778 #endif // __FASTJET_SEARCHTREE_HH__ 
Selector operator*(const Selector &s1, const Selector &s2)
successive application of 2 selectors 
 
bool operator==(const PseudoJet &a, const PseudoJet &b)
returns true if the 4 momentum components of the two PseudoJets are identical and all the internal in...
 
bool operator!=(const PseudoJet &a, const PseudoJet &b)
inequality test which is exact opposite of operator==