ncbi_tree.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:23k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbi_tree.hpp,v $
  4.  * PRODUCTION Revision 1000.4  2004/06/01 19:07:49  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.33
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef CORELIB___NCBI_TREE__HPP
  10. #define CORELIB___NCBI_TREE__HPP
  11. /*  $Id: ncbi_tree.hpp,v 1000.4 2004/06/01 19:07:49 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Author: Anatoliy Kuznetsov
  37.  *
  38.  * File Description:
  39.  *  Tree container.
  40.  *
  41.  */
  42. #include <corelib/ncbistd.hpp>
  43. #include <list>
  44. #include <stack>
  45. BEGIN_NCBI_SCOPE
  46. /** @addtogroup Tree
  47.  *
  48.  * @{
  49.  */
  50. /////////////////////////////////////////////////////////////////////////////
  51. ///
  52. ///    Bi-directionaly linked N way tree.
  53. ///
  54. template <class TValue> 
  55. class CTreeNode
  56. {
  57. public:
  58.     typedef TValue                     TValueType;
  59.     typedef CTreeNode<TValue>          TTreeType;
  60.     typedef list<TTreeType*>           TNodeList;
  61.     typedef list<const TTreeType*>     TConstNodeList;
  62.     typedef typename TNodeList::iterator        TNodeList_I;
  63.     typedef typename TNodeList::const_iterator  TNodeList_CI;
  64.     /// Tree node construction
  65.     ///
  66.     /// @param
  67.     ///   value - node value
  68.     CTreeNode(const TValue& value = TValue());
  69.     ~CTreeNode();
  70.     CTreeNode(const TTreeType& tree);
  71.     CTreeNode& operator =(const TTreeType& tree);
  72.     /// Get node's parent
  73.     ///
  74.     /// @return parent to the current node, NULL if it is a top
  75.     /// of the tree
  76.     const TTreeType* GetParent() const { return m_Parent; }
  77.     /// Get node's parent
  78.     ///
  79.     /// @return parent to the current node, NULL if it is a top
  80.     /// of the tree
  81.     TTreeType* GetParent() { return m_Parent; }
  82.     /// Get the topmost node 
  83.     ///
  84.     /// @return global parent of the current node, this if it is a top
  85.     /// of the tree
  86.     const TTreeType* GetRoot() const;
  87.     /// Get the topmost node 
  88.     ///
  89.     /// @return global parent of the current node, this if it is a top
  90.     /// of the tree
  91.     TTreeType* GetRoot();
  92.     /// Return first const iterator on subnode list
  93.     TNodeList_CI SubNodeBegin() const { return m_Nodes.begin(); }
  94.     /// Return first iterator on subnode list
  95.     TNodeList_I SubNodeBegin() { return m_Nodes.begin(); }
  96.     /// Return last const iterator on subnode list
  97.     TNodeList_CI SubNodeEnd() const { return m_Nodes.end(); }
  98.     /// Return last iterator on subnode list
  99.     TNodeList_I SubNodeEnd() { return m_Nodes.end(); }
  100.     /// Return node's value
  101.     const TValue& GetValue() const { return m_Value; }
  102.     /// Return node's value
  103.     TValue& GetValue() { return m_Value; }
  104.     /// Set value for the node
  105.     void SetValue(const TValue& value) { m_Value = value; }
  106.     /// Remove subnode of the current node. Must be direct subnode.
  107.     ///
  108.     /// If subnode is not connected directly with the current node
  109.     /// the call has no effect.
  110.     ///
  111.     /// @param 
  112.     ///    subnode  direct subnode pointer
  113.     void RemoveNode(TTreeType* subnode);
  114.     /// Remove subnode of the current node. Must be direct subnode.
  115.     ///
  116.     /// If subnode is not connected directly with the current node
  117.     /// the call has no effect.
  118.     ///
  119.     /// @param 
  120.     ///    it  subnode iterator
  121.     void RemoveNode(TNodeList_I it);
  122.     enum EDeletePolicy
  123.     {
  124.         eDelete,
  125.         eNoDelete
  126.     };
  127.     /// Remove all immediate subnodes
  128.     ///
  129.     /// @param del
  130.     ///    Subnode delete policy
  131.     void RemoveAllSubNodes(EDeletePolicy del = eDelete);
  132.     /// Remove the subtree from the tree without freeing it
  133.     ///
  134.     /// If subnode is not connected directly with the current node
  135.     /// the call has no effect. The caller is responsible for deletion
  136.     /// of the returned subtree.
  137.     ///
  138.     /// @param 
  139.     ///    subnode  direct subnode pointer
  140.     ///
  141.     /// @return subtree pointer or NULL if requested subnode does not exist
  142.     TTreeType* DetachNode(TTreeType* subnode);
  143.     /// Remove the subtree from the tree without freeing it
  144.     ///
  145.     /// If subnode is not connected directly with the current node
  146.     /// the call has no effect. The caller is responsible for deletion
  147.     /// of the returned subtree.
  148.     ///
  149.     /// @param 
  150.     ///    subnode  direct subnode pointer
  151.     ///
  152.     /// @return subtree pointer or NULL if requested subnode does not exist
  153.     TTreeType* DetachNode(TNodeList_I it);
  154.     /// Add new subnode
  155.     ///
  156.     /// @param 
  157.     ///    subnode subnode pointer
  158.     void AddNode(TTreeType* subnode);
  159.     /// Add new subnode whose value is (a copy of) val
  160.     ///
  161.     /// @param 
  162.     ///    val value reference
  163.     ///
  164.     /// @return pointer to new subtree
  165.     CTreeNode<TValue>* AddNode(const TValue& val = TValue());
  166.     /// Remove all subnodes from the source node and attach them to the
  167.     /// current tree (node). Source node cannot be an ancestor of the 
  168.     /// current node
  169.     void MoveSubnodes(TTreeType* src_tree_node);
  170.     /// Insert new subnode before the specified location in the subnode list
  171.     ///
  172.     /// @param
  173.     ///    it subnote iterator idicates the location of the new subtree
  174.     /// @param 
  175.     ///    subnode subtree pointer
  176.     void InsertNode(TNodeList_I it, TTreeType* subnode);
  177.     /// Report whether this is a leaf node
  178.     ///
  179.     /// @return TRUE if this is a leaf node (has no children),
  180.     /// false otherwise
  181.     bool IsLeaf() const { return m_Nodes.empty(); };
  182.     /// Check if node is a direct or indirect parent of this node
  183.     ///
  184.     /// @param  tree_node
  185.     ///    Node candidate
  186.     /// @return TRUE if tree_node is a direct or indirect parent
  187.     bool IsParent(const TTreeType& tree_node) const;
  188. protected:
  189.     void CopyFrom(const TTreeType& tree);
  190.     void SetParent(TTreeType* parent_node) { m_Parent = parent_node; }
  191.     const TNodeList& GetSubNodes() const { return m_Nodes; }
  192. protected:
  193.     TTreeType*         m_Parent; ///< Pointer on the parent node
  194.     TNodeList          m_Nodes;  ///< List of dependent nodes
  195.     TValue             m_Value;  ///< Node value
  196. };
  197. template <class TId, class TValue>
  198. struct CTreePair
  199. {
  200.     TId       id;
  201.     TValue    value;
  202.     CTreePair() {}
  203.     CTreePair(const TId& tid, const TValue& tvalue)
  204.     : id(tid),
  205.       value(tvalue)
  206.     {}
  207.     TId GetId() const { return id; }
  208. };
  209. /////////////////////////////////////////////////////////////////////////////
  210. ///
  211. ///    Bi-directionaly linked N way tree.
  212. ///    Parameterized by id - value pair
  213. template <class TId, class TValue> class CTreePairNode
  214.     : public CTreeNode< CTreePair<TId, TValue> >
  215. {
  216. public:
  217.     typedef TId                                  TIdType;
  218.     typedef TValue                               TValueType;
  219.     typedef CTreeNode<CTreePair<TId, TValue> >   TParent;
  220.     typedef CTreePair<TId, TValue>               TTreePair;
  221.     typedef CTreePairNode<TId, TValue>           TPairTreeType;
  222.     typedef list<TPairTreeType*>                 TPairTreeNodeList;
  223.     typedef list<const TPairTreeType*>           TConstPairTreeNodeList;
  224. public:
  225.     CTreePairNode(const TId& id = TId(), const TValue& value = TValue());
  226.     CTreePairNode(const CTreePairNode<TId, TValue>& tr);
  227.     CTreePairNode<TId, TValue>& operator=(const CTreePairNode<TId, TValue>& tr);
  228.     /// Add new subnode whose value is (a copy of) val
  229.     ///
  230.     /// @param 
  231.     ///    val value reference
  232.     ///
  233.     /// @return pointer to new subtree
  234.     CTreePairNode<TId, TValue>* AddNode(const TId& id, const TValue& value);
  235.     /// Return node's value
  236.     const TValueType& GetValue() const { return this->m_Value.value; }
  237.     /// Return node's id
  238.     const TIdType& GetId() const { return this->m_Value.id; }
  239.     /// Return node's value
  240.     TValueType& GetValue() { return this->m_Value.value; }
  241.     /// Return node's id
  242.     TIdType& GetId() { return this->m_Value.id; }
  243.     /// Set value for the node
  244.     void SetValue(const TValue& value) { this->m_Value.value = value; }
  245.     /// Set id for the node
  246.     void SetId(const TId& id) { this->m_Value.id = id; }
  247.     /// Find tree nodes corresponding to the path from the top
  248.     ///
  249.     /// @param node_path
  250.     ///    hierachy of node ids to search for
  251.     /// @param res
  252.     ///    list of discovered found nodes
  253.     void FindNodes(const list<TId>& node_path, TPairTreeNodeList* res);
  254.     /// Find tree nodes corresponding to the path from the top
  255.     ///
  256.     /// @param node_path
  257.     ///    hierachy of node ids to search for
  258.     /// @param res
  259.     ///    list of discovered found nodes (const pointers)
  260.     void FindNodes(const list<TId>& node_path, TConstPairTreeNodeList* res) const;
  261. };
  262. /////////////////////////////////////////////////////////////////////////////
  263. //
  264. //  Tree algorithms
  265. //
  266. /// Tree traverse code returned by the traverse predicate function
  267. enum ETreeTraverseCode
  268. {
  269.     eTreeTraverse,           ///< Keep traversal
  270.     eTreeTraverseStop,       ///< Stop traversal (return form algorithm)
  271.     eTreeTraverseStepOver    ///< Do not traverse current node (pick the next one)
  272. };
  273. /// Depth-first tree traversal algorithm.
  274. ///
  275. /// Takes tree and visitor function and calls function for every 
  276. /// node in the tree.
  277. ///
  278. /// Functor should have the next prototype:
  279. /// ETreeTraverseCode Func(TreeNode& node, int delta_level)
  280. ///  where node is a reference to the visited node and delta_level 
  281. ///  reflects the current traverse direction(depth wise) in the tree, 
  282. ///   0  - algorithm stays is on the same level
  283. ///   1  - we are going one level deep into the tree (from the root)
  284. ///  -1  - we are traveling back by one level (getting close to the root)
  285. ///
  286. /// Algorithm calls the visitor function on the way back so it revisits
  287. /// some tree nodes. It is possible to implement both variants of tree 
  288. /// traversal (pre-order and post-order)
  289. /// Visitor controls the traversal by returning ETreeTraverseCode
  290. ///
  291. /// @sa ETreeTraverseCode
  292. ///
  293. template<class TTreeNode, class Fun>
  294. Fun TreeDepthFirstTraverse(TTreeNode& tree_node, Fun func)
  295. {
  296.     int delta_level = 0;
  297.     ETreeTraverseCode stop_scan;
  298.     stop_scan = func(tree_node, delta_level);
  299.     switch (stop_scan) {
  300.         case eTreeTraverseStop:
  301.         case eTreeTraverseStepOver:
  302.             return func;
  303.         case eTreeTraverse:
  304.             break;
  305.     }
  306.     if (stop_scan)
  307.         return func;
  308.     delta_level = 1;
  309.     TTreeNode* tr = &tree_node;
  310.     typedef typename TTreeNode::TNodeList_I TTreeNodeIterator;
  311.     TTreeNodeIterator it = tr->SubNodeBegin();
  312.     TTreeNodeIterator it_end = tr->SubNodeEnd();
  313.     if (it == it_end)
  314.         return func;
  315.     stack<TTreeNodeIterator> tree_stack;
  316.     while (true) {
  317.         tr = *it;
  318.         stop_scan = eTreeTraverse;
  319.         if (tr) {
  320.             stop_scan = func(*tr, delta_level);
  321.             switch (stop_scan) {
  322.                 case eTreeTraverseStop:
  323.                     return func;
  324.                 case eTreeTraverse:
  325.                 case eTreeTraverseStepOver:
  326.                     break;
  327.             }
  328.         }
  329.         if ( (stop_scan != eTreeTraverseStepOver) &&
  330.              (delta_level >= 0) && 
  331.              (!tr->IsLeaf())) {  // sub-node, going down
  332.             tree_stack.push(it);
  333.             it = tr->SubNodeBegin();
  334.             it_end = tr->SubNodeEnd();
  335.             delta_level = 1;
  336.             continue;
  337.         }
  338.         ++it;
  339.         if (it == it_end) { // end of level, going up
  340.             if (tree_stack.empty()) {
  341.                 break;
  342.             }
  343.             it = tree_stack.top();
  344.             tree_stack.pop();
  345.             tr = *it;
  346.             it_end = tr->GetParent()->SubNodeEnd();
  347.             delta_level = -1;
  348.             continue;
  349.         }
  350.         // same level 
  351.         delta_level = 0;
  352.     } // while
  353.     func(tree_node, -1);
  354.     return func;
  355. }
  356. /////////////////////////////////////////////////////////////////////////////
  357. //
  358. //  CTreeNode<TValue>
  359. //
  360. template<class TValue>
  361. CTreeNode<TValue>::CTreeNode(const TValue& value)
  362. : m_Parent(0),
  363.   m_Value(value)
  364. {}
  365. template<class TValue>
  366. CTreeNode<TValue>::~CTreeNode()
  367. {
  368.     _ASSERT(m_Parent == 0);
  369.     ITERATE(typename TNodeList, it, m_Nodes) {
  370.         CTreeNode* node = *it;
  371.         node->m_Parent = 0;
  372.         delete node;
  373.     }
  374. }
  375. template<class TValue>
  376. CTreeNode<TValue>::CTreeNode(const TTreeType& tree)
  377. : m_Parent(0),
  378.   m_Value(tree.m_Value)
  379. {
  380.     CopyFrom(tree);
  381. }
  382. template<class TValue>
  383. CTreeNode<TValue>& CTreeNode<TValue>::operator=(const TTreeType& tree)
  384. {
  385.     NON_CONST_ITERATE(typename TNodeList, it, m_Nodes) {
  386.         CTreeNode* node = *it;
  387.         delete node;
  388.     }
  389.     m_Nodes.clear();
  390.     CopyFrom(tree);
  391.     return *this;
  392. }
  393. template<class TValue>
  394. void CTreeNode<TValue>::CopyFrom(const TTreeType& tree)
  395. {
  396.     ITERATE(typename TNodeList, it, tree.m_Nodes) {
  397.         const CTreeNode* src_node = *it;
  398.         CTreeNode* new_node = new CTreeNode(*src_node);
  399.         AddNode(new_node);
  400.     }
  401. }
  402. template<class TValue>
  403. void CTreeNode<TValue>::RemoveNode(TTreeType* subnode)
  404. {
  405.     NON_CONST_ITERATE(typename TNodeList, it, m_Nodes) {
  406.         CTreeNode* node = *it;
  407.         if (node == subnode) {
  408.             m_Nodes.erase(it);
  409.             node->m_Parent = 0;
  410.             delete node;
  411.             break;
  412.         }
  413.     }    
  414. }
  415. template<class TValue>
  416. void CTreeNode<TValue>::RemoveNode(TNodeList_I it)
  417. {
  418.     CTreeNode* node = *it;
  419.     node->m_Parent = 0;
  420.     m_Nodes.erase(it);
  421.     delete node;
  422. }
  423. template<class TValue>
  424. typename CTreeNode<TValue>::TTreeType* 
  425. CTreeNode<TValue>::DetachNode(typename CTreeNode<TValue>::TTreeType* subnode)
  426. {
  427.     NON_CONST_ITERATE(typename TNodeList, it, m_Nodes) {
  428.         CTreeNode* node = *it;
  429.         if (node == subnode) {
  430.             m_Nodes.erase(it);
  431.             node->SetParent(0);
  432.             return node;
  433.         }
  434.     }        
  435.     return 0;
  436. }
  437. template<class TValue>
  438. typename CTreeNode<TValue>::TTreeType* 
  439. CTreeNode<TValue>::DetachNode(typename CTreeNode<TValue>::TNodeList_I it)
  440. {
  441.     CTreeNode* node = *it;
  442.     m_Nodes.erase(it);
  443.     node->SetParent(0);
  444.     return node;
  445. }
  446. template<class TValue>
  447. void CTreeNode<TValue>::AddNode(typename CTreeNode<TValue>::TTreeType* subnode)
  448. {
  449.     _ASSERT(subnode != this);
  450.     m_Nodes.push_back(subnode);
  451.     subnode->SetParent(this);
  452. }
  453. template<class TValue>
  454. CTreeNode<TValue>* CTreeNode<TValue>::AddNode(const TValue& val)
  455. {
  456.     TTreeType* subnode = new TTreeType(val);
  457.     AddNode(subnode);
  458.     return subnode;
  459. }
  460. template<class TValue>
  461. void CTreeNode<TValue>::MoveSubnodes(TTreeType* src_tree_node)
  462. {
  463.     _ASSERT(!IsParent(*src_tree_node));
  464.     TNodeList& src_nodes = src_tree_node->m_Nodes;
  465.     ITERATE(typename TNodeList, it, src_nodes) {
  466.         AddNode(*it);
  467.     }
  468.     src_nodes.clear();
  469. }
  470. template<class TValue>
  471. void CTreeNode<TValue>::InsertNode(TNodeList_I it,
  472.                                    TTreeType* subnode)
  473. {
  474.     m_Nodes.insert(it, subnode);
  475.     subnode->SetParent(this);
  476. }
  477. template<class TValue>
  478. void CTreeNode<TValue>::RemoveAllSubNodes(EDeletePolicy del)
  479. {
  480.     if (del == eDelete) {
  481.         NON_CONST_ITERATE(typename TNodeList, it, m_Nodes) {
  482.             CTreeNode* node = *it;
  483.             delete node;
  484.         }
  485.     }
  486.     m_Nodes.clear();
  487. }
  488. template<class TValue>
  489. const typename CTreeNode<TValue>::TTreeType* CTreeNode<TValue>::GetRoot() const
  490. {
  491.     const TTreeType* node_ptr = this;
  492.     while (true) {
  493.         const TTreeType* parent = node_ptr->GetParent();
  494.         if (parent)
  495.             node_ptr = parent;
  496.         else
  497.             break;
  498.     }
  499.     return node_ptr;
  500. }
  501. template<class TValue>
  502. typename CTreeNode<TValue>::TTreeType* CTreeNode<TValue>::GetRoot()
  503. {
  504.     TTreeType* node_ptr = this;
  505.     while (true) {
  506.         TTreeType* parent = node_ptr->GetParent();
  507.         if (parent) 
  508.             node_ptr = parent;
  509.         else 
  510.             break;
  511.     }
  512.     return node_ptr;
  513. }
  514. template<class TValue>
  515. bool CTreeNode<TValue>::IsParent(const TTreeType& tree_node) const
  516. {
  517.     _ASSERT(this != &tree_node);
  518.     const TTreeType* node_ptr = GetParent();
  519.     while (node_ptr) {
  520.         if (node_ptr == &tree_node)
  521.             return true;
  522.         node_ptr = node_ptr->GetParent();
  523.     }
  524.     return false;
  525. }
  526. /////////////////////////////////////////////////////////////////////////////
  527. //
  528. //  CTreePairNode<TId, TValue>
  529. //
  530. template<class TId, class TValue>
  531. CTreePairNode<TId, TValue>::CTreePairNode(const TId& id, const TValue& value)
  532.  : TParent(TTreePair(id, value))
  533. {}
  534. template<class TId, class TValue>
  535. CTreePairNode<TId, TValue>::CTreePairNode(const CTreePairNode<TId, TValue>& tr)
  536. : TParent(tr)
  537. {}
  538. template<class TId, class TValue>
  539. CTreePairNode<TId, TValue>& 
  540. CTreePairNode<TId, TValue>::operator=(const CTreePairNode<TId, TValue>& tr)
  541. {
  542.     TParent::operator=(tr);
  543. }
  544. template<class TId, class TValue>
  545. CTreePairNode<TId, TValue>*
  546. CTreePairNode<TId, TValue>::AddNode(const TId& id, const TValue& value)
  547. {
  548.     return (CTreePairNode<TId, TValue>*)TParent::AddNode(TTreePair(id, value));
  549. }
  550. template<class TId, class TValue>
  551. void CTreePairNode<TId, TValue>::FindNodes(const list<TId>& node_path, 
  552.                                            TPairTreeNodeList*       res)
  553. {
  554.     typename TParent::TTreeType* tr = this;
  555.     ITERATE(typename list<TId>, sit, node_path) {
  556.         const TId& search_id = *sit;
  557.         bool sub_level_found = false;
  558.         typename TParent::TNodeList_I it = tr->SubNodeBegin();
  559.         typename TParent::TNodeList_I it_end = tr->SubNodeEnd();
  560.         for (; it != it_end; ++it) {
  561.             TParent* node = *it;
  562.             const TTreePair& node_pair = node->GetValue();
  563.             if (node_pair.id == search_id) {
  564.                 tr = node;
  565.                 sub_level_found = true;
  566.                 break;
  567.             }
  568.         } // for it
  569.         if (!sub_level_found) {
  570.             return;
  571.         }
  572.         sub_level_found = false;
  573.     } // ITERATE
  574.     res.push_back(tr);
  575. }
  576. template<class TId, class TValue>
  577. void CTreePairNode<TId, TValue>::FindNodes(const list<TId>&         node_path, 
  578.                                            TConstPairTreeNodeList*  res) const
  579. {
  580.     const typename TParent::TTreeType* tr = this;
  581.     ITERATE(typename list<TId>, sit, node_path) {
  582.         const TId& search_id = *sit;
  583.         bool sub_level_found = false;
  584.         typename TParent::TNodeList_CI it = tr->SubNodeBegin();
  585.         typename TParent::TNodeList_CI it_end = tr->SubNodeEnd();
  586.         for (; it != it_end; ++it) {
  587.             const TParent* node = *it;
  588.             const TTreePair& node_pair = node->GetValue();
  589.             if (node_pair.id == search_id) {
  590.                 tr = node;
  591.                 sub_level_found = true;
  592.                 break;
  593.             }
  594.         } // for it
  595.         if (!sub_level_found) {
  596.             return;
  597.         }
  598.         sub_level_found = false;
  599.     } // ITERATE
  600.     res->push_back((TPairTreeType*)tr);
  601. }
  602. /* @} */
  603. END_NCBI_SCOPE
  604. /*
  605.  * ===========================================================================
  606.  * $Log: ncbi_tree.hpp,v $
  607.  * Revision 1000.4  2004/06/01 19:07:49  gouriano
  608.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.33
  609.  *
  610.  * Revision 1.33  2004/04/26 14:47:51  ucko
  611.  * Qualify dependent names with "this->" as needed (by GCC 3.4).
  612.  *
  613.  * Revision 1.32  2004/04/19 16:00:14  kuznets
  614.  * Algorithms migrated to <algo/tree>
  615.  *
  616.  * Revision 1.31  2004/04/12 15:17:46  vasilche
  617.  * Added missing typename keyword.
  618.  *
  619.  * Revision 1.30  2004/04/12 13:28:25  kuznets
  620.  * + MoveSubnodes
  621.  *
  622.  * Revision 1.29  2004/04/09 15:27:30  gorelenk
  623.  * Added missed 'typename' (s) .
  624.  *
  625.  * Revision 1.28  2004/04/09 14:25:56  kuznets
  626.  * + TreeReRoot, improved internal data integrity diagnostics
  627.  *
  628.  * Revision 1.27  2004/04/08 18:34:19  kuznets
  629.  * attached code to a doxygen group
  630.  * +TreePrinting template (for debug purposes)
  631.  *
  632.  * Revision 1.26  2004/04/08 12:22:56  kuznets
  633.  * Fixed compilation warnings
  634.  *
  635.  * Revision 1.25  2004/04/08 11:47:46  kuznets
  636.  * + TreeFindCommonParent, + TreeTraceToRoot
  637.  *
  638.  * Revision 1.24  2004/04/06 15:53:16  kuznets
  639.  * Minor correction in the comments
  640.  *
  641.  * Revision 1.23  2004/03/10 15:59:33  kuznets
  642.  * TreeDepthFirstTraverse fixed bug in tree iteration logic
  643.  * (corner case for empty tree)
  644.  *
  645.  * Revision 1.22  2004/02/17 19:07:27  kuznets
  646.  * GCC warning fix
  647.  *
  648.  * Revision 1.21  2004/01/29 20:03:17  jcherry
  649.  * Added default value for AddNode(const TValue& val)
  650.  *
  651.  * Revision 1.20  2004/01/15 20:05:53  yazhuk
  652.  * Added return falue to operator=
  653.  *
  654.  * Revision 1.19  2004/01/14 17:38:05  kuznets
  655.  * TreeDepthFirstTraverse improved to support more traversal options
  656.  * (ETreeTraverseCode)
  657.  *
  658.  * Revision 1.18  2004/01/14 17:02:32  kuznets
  659.  * + PairTreeBackTraceNode
  660.  *
  661.  * Revision 1.17  2004/01/14 16:24:17  kuznets
  662.  * + CTreeNode::RemoveAllSubNodes
  663.  *
  664.  * Revision 1.16  2004/01/14 15:25:38  kuznets
  665.  * Fixed bug in PairTreeTraceNode algorithm
  666.  *
  667.  * Revision 1.15  2004/01/14 14:18:21  kuznets
  668.  * +TreeDepthFirstTraverse algorithm
  669.  *
  670.  * Revision 1.14  2004/01/12 22:04:03  ucko
  671.  * Fix typo caught by MIPSpro.
  672.  *
  673.  * Revision 1.13  2004/01/12 21:03:42  ucko
  674.  * Fix use of typename in PairTreeTraceNode<>, silently added in last revision.
  675.  *
  676.  * Revision 1.12  2004/01/12 20:09:22  kuznets
  677.  * Renamed CTreeNWay to CTreeNode
  678.  *
  679.  * Revision 1.11  2004/01/12 18:01:15  jcherry
  680.  * Added IsLeaf method
  681.  *
  682.  * Revision 1.10  2004/01/12 16:49:48  kuznets
  683.  * CTreePairNode added id, value accessor functions
  684.  *
  685.  * Revision 1.9  2004/01/12 15:26:22  kuznets
  686.  * Fixed various compilation warnings (GCC & WorkShop)
  687.  *
  688.  * Revision 1.8  2004/01/12 15:01:58  kuznets
  689.  * +CTreePairNode::FindNodes
  690.  *
  691.  * Revision 1.7  2004/01/09 19:01:39  kuznets
  692.  * Fixed compilation for GCC
  693.  *
  694.  * Revision 1.6  2004/01/09 17:15:11  kuznets
  695.  * Cosmetic cleanup
  696.  *
  697.  * Revision 1.5  2004/01/09 13:27:39  kuznets
  698.  * Cosmetic fixes. nodelist_iterator renamed to match the NCBI coding policy.
  699.  *
  700.  * Revision 1.4  2004/01/07 21:38:29  jcherry
  701.  * Added method for adding child node given a value
  702.  *
  703.  * Revision 1.3  2004/01/07 21:10:58  jcherry
  704.  * Compile fixes
  705.  *
  706.  * Revision 1.2  2004/01/07 17:21:53  kuznets
  707.  * + template implementation
  708.  *
  709.  * Revision 1.1  2004/01/07 13:17:10  kuznets
  710.  * Initial revision
  711.  *
  712.  *
  713.  * ==========================================================================
  714.  */
  715. #endif