tree_algorithms.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,626 行 · 第 1/4 页

HPP
1,626
字号
      NodeTraits::set_right(new_node, NodeTraits::get_right(node_to_be_replaced));      NodeTraits::set_parent(new_node, NodeTraits::get_parent(node_to_be_replaced));      //Now adjust adjacent nodes for newly inserted node      if((temp = NodeTraits::get_left(new_node))){         NodeTraits::set_parent(temp, new_node);      }      if((temp = NodeTraits::get_right(new_node))){         NodeTraits::set_parent(temp, new_node);      }      if((temp = NodeTraits::get_parent(new_node)) &&         //The header has been already updated so avoid it         temp != header){         if(NodeTraits::get_left(temp) == node_to_be_replaced){            NodeTraits::set_left(temp, new_node);         }         if(NodeTraits::get_right(temp) == node_to_be_replaced){            NodeTraits::set_right(temp, new_node);         }      }   }   //! <b>Requires</b>: p is a node from the tree except the header.   //!    //! <b>Effects</b>: Returns the next node of the tree.   //!    //! <b>Complexity</b>: Average constant time.   //!    //! <b>Throws</b>: Nothing.   static node_ptr next_node(node_ptr p)   {      node_ptr p_right(NodeTraits::get_right(p));      if(p_right){         return minimum(p_right);      }      else {         node_ptr x = NodeTraits::get_parent(p);         while(p == NodeTraits::get_right(x)){            p = x;            x = NodeTraits::get_parent(x);         }         return NodeTraits::get_right(p) != x ? x : uncast(p);      }   }   //! <b>Requires</b>: p is a node from the tree except the leftmost node.   //!    //! <b>Effects</b>: Returns the previous node of the tree.   //!    //! <b>Complexity</b>: Average constant time.   //!    //! <b>Throws</b>: Nothing.   static node_ptr prev_node(node_ptr p)   {      if(is_header(p)){         return maximum(NodeTraits::get_parent(p));      }      else if(NodeTraits::get_left(p)){         return maximum(NodeTraits::get_left(p));      }      else {         node_ptr x = NodeTraits::get_parent(p);         while(p == NodeTraits::get_left(x)){            p = x;            x = NodeTraits::get_parent(x);         }         return x;      }   }   //! <b>Requires</b>: p is a node of a tree but not the header.   //!    //! <b>Effects</b>: Returns the minimum node of the subtree starting at p.   //!    //! <b>Complexity</b>: Logarithmic to the size of the subtree.   //!    //! <b>Throws</b>: Nothing.   static node_ptr minimum (node_ptr p)   {      for(node_ptr p_left = NodeTraits::get_left(p)         ;p_left         ;p_left = NodeTraits::get_left(p)){         p = p_left;      }      return p;   }   //! <b>Requires</b>: p is a node of a tree but not the header.   //!    //! <b>Effects</b>: Returns the maximum node of the subtree starting at p.   //!    //! <b>Complexity</b>: Logarithmic to the size of the subtree.   //!    //! <b>Throws</b>: Nothing.   static node_ptr maximum(node_ptr p)   {      for(node_ptr p_right = NodeTraits::get_right(p)         ;p_right         ;p_right = NodeTraits::get_right(p)){         p = p_right;      }      return p;   }   //! <b>Requires</b>: node must not be part of any tree.   //!   //! <b>Effects</b>: After the function unique(node) == true.   //!    //! <b>Complexity</b>: Constant.   //!    //! <b>Throws</b>: Nothing.   //!   //! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.   static void init(node_ptr node)   {      NodeTraits::set_parent(node, node_ptr(0));      NodeTraits::set_left(node, node_ptr(0));      NodeTraits::set_right(node, node_ptr(0));    };   //! <b>Effects</b>: Returns true if node is in the same state as if called init(node)   //!    //! <b>Complexity</b>: Constant.   //!    //! <b>Throws</b>: Nothing.   static bool inited(const_node_ptr node)   {      return !NodeTraits::get_parent(node) &&              !NodeTraits::get_left(node)   &&             !NodeTraits::get_right(node)  ;   };   //! <b>Requires</b>: node must not be part of any tree.   //!   //! <b>Effects</b>: Initializes the header to represent an empty tree.   //!   unique(header) == true.   //!    //! <b>Complexity</b>: Constant.   //!    //! <b>Throws</b>: Nothing.   //!   //! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.   static void init_header(node_ptr header)   {      NodeTraits::set_parent(header, node_ptr(0));      NodeTraits::set_left(header, header);      NodeTraits::set_right(header, header);    }   //! <b>Requires</b>: "disposer" must be an object function   //!   taking a node_ptr parameter and shouldn't throw.   //!   //! <b>Effects</b>: Empties the target tree calling    //!   <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree   //!    except the header.   //!    //! <b>Complexity</b>: Linear to the number of element of the source tree plus the.   //!   number of elements of tree target tree when calling this function.   //!    //! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.   template<class Disposer>   static void clear_and_dispose(node_ptr header, Disposer disposer)   {      node_ptr source_root = NodeTraits::get_parent(header);      if(!source_root)         return;      dispose_subtree(source_root, disposer);      init_header(header);   }   //! <b>Requires</b>: header is the header of a tree.   //!    //! <b>Effects</b>: Unlinks the leftmost node from the tree, and   //!   updates the header link to the new leftmost node.   //!    //! <b>Complexity</b>: Average complexity is constant time.   //!    //! <b>Throws</b>: Nothing.   //!    //! <b>Notes</b>: This function breaks the tree and the tree can   //!   only be used for more unlink_leftmost_without_rebalance calls.   //!   This function is normally used to achieve a step by step   //!   controlled destruction of the tree.   static node_ptr unlink_leftmost_without_rebalance(node_ptr header)   {      node_ptr leftmost = NodeTraits::get_left(header);      if (leftmost == header)         return node_ptr(0);      node_ptr leftmost_parent(NodeTraits::get_parent(leftmost));      node_ptr leftmost_right (NodeTraits::get_right(leftmost));      bool is_root = leftmost_parent == header;      if (leftmost_right){         NodeTraits::set_parent(leftmost_right, leftmost_parent);         NodeTraits::set_left(header, tree_algorithms::minimum(leftmost_right));         if (is_root)            NodeTraits::set_parent(header, leftmost_right);         else            NodeTraits::set_left(NodeTraits::get_parent(header), leftmost_right);      }      else if (is_root){         NodeTraits::set_parent(header, node_ptr(0));         NodeTraits::set_left(header,  header);         NodeTraits::set_right(header, header);      }      else{         NodeTraits::set_left(leftmost_parent, node_ptr(0));         NodeTraits::set_left(header, leftmost_parent);      }      return leftmost;   }   //! <b>Requires</b>: node is a node of the tree but it's not the header.   //!    //! <b>Effects</b>: Returns the number of nodes of the subtree.   //!    //! <b>Complexity</b>: Linear time.   //!    //! <b>Throws</b>: Nothing.   static std::size_t count(const_node_ptr subtree)   {      if(!subtree) return 0;      std::size_t count = 0;      node_ptr p = minimum(uncast(subtree));      bool continue_looping = true;      while(continue_looping){         ++count;         node_ptr p_right(NodeTraits::get_right(p));         if(p_right){            p = minimum(p_right);         }         else {            for(;;){               node_ptr q;               if (p == subtree){                  continue_looping = false;                  break;               }               q = p;               p = NodeTraits::get_parent(p);               if (NodeTraits::get_left(p) == q)                  break;            }         }      }      return count;   }   //! <b>Requires</b>: node is a node of the tree but it's not the header.   //!    //! <b>Effects</b>: Returns the number of nodes of the subtree.   //!    //! <b>Complexity</b>: Linear time.   //!    //! <b>Throws</b>: Nothing.   static std::size_t size(const_node_ptr header)   {      node_ptr beg(begin_node(header));      node_ptr end(end_node(header));      std::size_t i = 0;      for(;beg != end; beg = next_node(beg)) ++i;      return i;   }   //! <b>Requires</b>: header1 and header2 must be the header nodes   //!  of two trees.   //!    //! <b>Effects</b>: Swaps two trees. After the function header1 will contain    //!   links to the second tree and header2 will have links to the first tree.   //!    //! <b>Complexity</b>: Constant.    //!    //! <b>Throws</b>: Nothing.   static void swap_tree(node_ptr header1, node_ptr header2)   {      if(header1 == header2)         return;         node_ptr tmp;      //Parent swap      tmp = NodeTraits::get_parent(header1);      NodeTraits::set_parent(header1, NodeTraits::get_parent(header2));      NodeTraits::set_parent(header2, tmp);      //Left swap      tmp = NodeTraits::get_left(header1);      NodeTraits::set_left(header1, NodeTraits::get_left(header2));      NodeTraits::set_left(header2, tmp);      //Right swap      tmp = NodeTraits::get_right(header1);      NodeTraits::set_right(header1, NodeTraits::get_right(header2));      NodeTraits::set_right(header2, tmp);      //Now test parent      node_ptr h1_parent(NodeTraits::get_parent(header1));      if(h1_parent){         NodeTraits::set_parent(h1_parent, header1);      }      else{         NodeTraits::set_left(header1, header1);         NodeTraits::set_right(header1, header1);      }      node_ptr h2_parent(NodeTraits::get_parent(header2));      if(h2_parent){         NodeTraits::set_parent(h2_parent, header2);      }      else{         NodeTraits::set_left(header2, header2);         NodeTraits::set_right(header2, header2);      }   }   static bool is_header(const_node_ptr p)   {/*      node_ptr p_parent = NodeTraits::get_parent(p);      if(!p_parent)         return true;      if(!NodeTraits::get_parent(p_parent) != p)         return false;      if(NodeTraits::get_left(p) != 0){         if(NodeTraits::get_parent(NodeTraits::get_left(p)) != p){            is_header = true;         }         if(NodeTraits::get_parent(p) == NodeTraits::get_left(p)){            is_header = true;         }      }*/            bool is_header = false;      if(NodeTraits::get_parent(p) == p){         is_header = true;      }      else if(NodeTraits::get_parent(NodeTraits::get_parent(p)) == p){         if(NodeTraits::get_left(p) != 0){            if(NodeTraits::get_parent(NodeTraits::get_left(p)) != p){               is_header = true;            }            if(NodeTraits::get_parent(p) == NodeTraits::get_left(p)){               is_header = true;            }         }      }      return is_header;   }   //! <b>Requires</b>: "header" must be the header node of a tree.   //!   KeyNodePtrCompare is a function object that induces a strict weak   //!   ordering compatible with the strict weak ordering used to create the   //!   the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.   //!   //! <b>Effects</b>: Returns an node_ptr to the element that is equivalent to   //!   "key" according to "comp" or "header" if that element does not exist.   //!   //! <b>Complexity</b>: Logarithmic.   //!    //! <b>Throws</b>: If "comp" throws.   template<class KeyType, class KeyNodePtrCompare>   static node_ptr find      (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)   {      node_ptr end = uncast(header);      node_ptr y = lower_bound(header, key, comp);      return (y == end || comp(key, y)) ? end : y;   }   //! <b>Requires</b>: "header" must be the header node of a tree.   //!   KeyNodePtrCompare is a function object that induces a strict weak   //!   ordering compatible with the strict weak ordering used to create the   //!   the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.   //!   //! <b>Effects</b>: Returns an a pair of node_ptr delimiting a range containing   //!   all elements that are equivalent to "key" according to "comp" or an   //!   empty range that indicates the position where those elements would be   //!   if they there are no equivalent elements.   //!   //! <b>Complexity</b>: Logarithmic.   //!    //! <b>Throws</b>: If "comp" throws.   template<class KeyType, class KeyNodePtrCompare>   static std::pair<node_ptr, node_ptr> equal_range      (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)   {      node_ptr y = uncast(header);      node_ptr x = NodeTraits::get_parent(header);      while(x){         if(comp(x, key)){            x = NodeTraits::get_right(x);         }         else if(comp(key, x)){            y = x;            x = NodeTraits::get_left(x);         }         else{            node_ptr xu(x), yu(y);            y = x, x = NodeTraits::get_left(x);            xu = NodeTraits::get_right(xu);            while(x){               if(comp(x, key)){                  x = NodeTraits::get_right(x);               }               else {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?