⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncbi_tree.hpp

📁 ncbi源码
💻 HPP
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbi_tree.hpp,v $ * PRODUCTION Revision 1000.4  2004/06/01 19:07:49  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.33 * PRODUCTION * =========================================================================== */#ifndef CORELIB___NCBI_TREE__HPP#define CORELIB___NCBI_TREE__HPP/*  $Id: ncbi_tree.hpp,v 1000.4 2004/06/01 19:07:49 gouriano Exp $ * =========================================================================== * *                            PUBLIC DOMAIN NOTICE *               National Center for Biotechnology Information * *  This software/database is a "United States Government Work" under the *  terms of the United States Copyright Act.  It was written as part of *  the author's official duties as a United States Government employee and *  thus cannot be copyrighted.  This software/database is freely available *  to the public for use. The National Library of Medicine and the U.S. *  Government have not placed any restriction on its use or reproduction. * *  Although all reasonable efforts have been taken to ensure the accuracy *  and reliability of the software and data, the NLM and the U.S. *  Government do not and cannot warrant the performance or results that *  may be obtained by using this software or data. The NLM and the U.S. *  Government disclaim all warranties, express or implied, including *  warranties of performance, merchantability or fitness for any particular *  purpose. * *  Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Anatoliy Kuznetsov * * File Description: *	 Tree container. * */#include <corelib/ncbistd.hpp>#include <list>#include <stack>BEGIN_NCBI_SCOPE/** @addtogroup Tree * * @{ *////////////////////////////////////////////////////////////////////////////////////    Bi-directionaly linked N way tree.///template <class TValue> class CTreeNode{public:    typedef TValue                     TValueType;    typedef CTreeNode<TValue>          TTreeType;    typedef list<TTreeType*>           TNodeList;    typedef list<const TTreeType*>     TConstNodeList;    typedef typename TNodeList::iterator        TNodeList_I;    typedef typename TNodeList::const_iterator  TNodeList_CI;    /// Tree node construction    ///    /// @param    ///   value - node value    CTreeNode(const TValue& value = TValue());    ~CTreeNode();    CTreeNode(const TTreeType& tree);    CTreeNode& operator =(const TTreeType& tree);    /// Get node's parent    ///    /// @return parent to the current node, NULL if it is a top    /// of the tree    const TTreeType* GetParent() const { return m_Parent; }    /// Get node's parent    ///    /// @return parent to the current node, NULL if it is a top    /// of the tree    TTreeType* GetParent() { return m_Parent; }    /// Get the topmost node     ///    /// @return global parent of the current node, this if it is a top    /// of the tree    const TTreeType* GetRoot() const;    /// Get the topmost node     ///    /// @return global parent of the current node, this if it is a top    /// of the tree    TTreeType* GetRoot();    /// Return first const iterator on subnode list    TNodeList_CI SubNodeBegin() const { return m_Nodes.begin(); }    /// Return first iterator on subnode list    TNodeList_I SubNodeBegin() { return m_Nodes.begin(); }    /// Return last const iterator on subnode list    TNodeList_CI SubNodeEnd() const { return m_Nodes.end(); }    /// Return last iterator on subnode list    TNodeList_I SubNodeEnd() { return m_Nodes.end(); }    /// Return node's value    const TValue& GetValue() const { return m_Value; }    /// Return node's value    TValue& GetValue() { return m_Value; }    /// Set value for the node    void SetValue(const TValue& value) { m_Value = value; }    /// Remove subnode of the current node. Must be direct subnode.    ///    /// If subnode is not connected directly with the current node    /// the call has no effect.    ///    /// @param     ///    subnode  direct subnode pointer    void RemoveNode(TTreeType* subnode);    /// Remove subnode of the current node. Must be direct subnode.    ///    /// If subnode is not connected directly with the current node    /// the call has no effect.    ///    /// @param     ///    it  subnode iterator    void RemoveNode(TNodeList_I it);    enum EDeletePolicy    {        eDelete,        eNoDelete    };    /// Remove all immediate subnodes    ///    /// @param del    ///    Subnode delete policy    void RemoveAllSubNodes(EDeletePolicy del = eDelete);    /// Remove the subtree from the tree without freeing it    ///    /// If subnode is not connected directly with the current node    /// the call has no effect. The caller is responsible for deletion    /// of the returned subtree.    ///    /// @param     ///    subnode  direct subnode pointer    ///    /// @return subtree pointer or NULL if requested subnode does not exist    TTreeType* DetachNode(TTreeType* subnode);    /// Remove the subtree from the tree without freeing it    ///    /// If subnode is not connected directly with the current node    /// the call has no effect. The caller is responsible for deletion    /// of the returned subtree.    ///    /// @param     ///    subnode  direct subnode pointer    ///    /// @return subtree pointer or NULL if requested subnode does not exist    TTreeType* DetachNode(TNodeList_I it);    /// Add new subnode    ///    /// @param     ///    subnode subnode pointer    void AddNode(TTreeType* subnode);    /// Add new subnode whose value is (a copy of) val    ///    /// @param     ///    val value reference    ///    /// @return pointer to new subtree    CTreeNode<TValue>* AddNode(const TValue& val = TValue());    /// Remove all subnodes from the source node and attach them to the    /// current tree (node). Source node cannot be an ancestor of the     /// current node    void MoveSubnodes(TTreeType* src_tree_node);    /// Insert new subnode before the specified location in the subnode list    ///    /// @param    ///    it subnote iterator idicates the location of the new subtree    /// @param     ///    subnode subtree pointer    void InsertNode(TNodeList_I it, TTreeType* subnode);    /// Report whether this is a leaf node    ///    /// @return TRUE if this is a leaf node (has no children),    /// false otherwise    bool IsLeaf() const { return m_Nodes.empty(); };    /// Check if node is a direct or indirect parent of this node    ///    /// @param  tree_node    ///    Node candidate    /// @return TRUE if tree_node is a direct or indirect parent    bool IsParent(const TTreeType& tree_node) const;protected:    void CopyFrom(const TTreeType& tree);    void SetParent(TTreeType* parent_node) { m_Parent = parent_node; }    const TNodeList& GetSubNodes() const { return m_Nodes; }protected:    TTreeType*         m_Parent; ///< Pointer on the parent node    TNodeList          m_Nodes;  ///< List of dependent nodes    TValue             m_Value;  ///< Node value};template <class TId, class TValue>struct CTreePair{    TId       id;    TValue    value;    CTreePair() {}    CTreePair(const TId& tid, const TValue& tvalue)    : id(tid),      value(tvalue)    {}    TId GetId() const { return id; }};///////////////////////////////////////////////////////////////////////////////////    Bi-directionaly linked N way tree.///    Parameterized by id - value pairtemplate <class TId, class TValue> class CTreePairNode    : public CTreeNode< CTreePair<TId, TValue> >{public:    typedef TId                                  TIdType;    typedef TValue                               TValueType;    typedef CTreeNode<CTreePair<TId, TValue> >   TParent;    typedef CTreePair<TId, TValue>               TTreePair;    typedef CTreePairNode<TId, TValue>           TPairTreeType;    typedef list<TPairTreeType*>                 TPairTreeNodeList;    typedef list<const TPairTreeType*>           TConstPairTreeNodeList;public:    CTreePairNode(const TId& id = TId(), const TValue& value = TValue());    CTreePairNode(const CTreePairNode<TId, TValue>& tr);    CTreePairNode<TId, TValue>& operator=(const CTreePairNode<TId, TValue>& tr);    /// Add new subnode whose value is (a copy of) val    ///    /// @param     ///    val value reference    ///    /// @return pointer to new subtree    CTreePairNode<TId, TValue>* AddNode(const TId& id, const TValue& value);    /// Return node's value    const TValueType& GetValue() const { return this->m_Value.value; }    /// Return node's id    const TIdType& GetId() const { return this->m_Value.id; }    /// Return node's value    TValueType& GetValue() { return this->m_Value.value; }    /// Return node's id    TIdType& GetId() { return this->m_Value.id; }    /// Set value for the node    void SetValue(const TValue& value) { this->m_Value.value = value; }    /// Set id for the node    void SetId(const TId& id) { this->m_Value.id = id; }    /// Find tree nodes corresponding to the path from the top    ///    /// @param node_path    ///    hierachy of node ids to search for    /// @param res    ///    list of discovered found nodes    void FindNodes(const list<TId>& node_path, TPairTreeNodeList* res);    /// Find tree nodes corresponding to the path from the top    ///    /// @param node_path    ///    hierachy of node ids to search for    /// @param res    ///    list of discovered found nodes (const pointers)    void FindNodes(const list<TId>& node_path, TConstPairTreeNodeList* res) const;};/////////////////////////////////////////////////////////////////////////////////  Tree algorithms///// Tree traverse code returned by the traverse predicate functionenum ETreeTraverseCode{    eTreeTraverse,           ///< Keep traversal    eTreeTraverseStop,       ///< Stop traversal (return form algorithm)    eTreeTraverseStepOver    ///< Do not traverse current node (pick the next one)};/// Depth-first tree traversal algorithm.////// Takes tree and visitor function and calls function for every /// node in the tree.////// Functor should have the next prototype:/// ETreeTraverseCode Func(TreeNode& node, int delta_level)///  where node is a reference to the visited node and delta_level ///  reflects the current traverse direction(depth wise) in the tree, ///   0  - algorithm stays is on the same level///   1  - we are going one level deep into the tree (from the root)///  -1  - we are traveling back by one level (getting close to the root)////// Algorithm calls the visitor function on the way back so it revisits/// some tree nodes. It is possible to implement both variants of tree /// traversal (pre-order and post-order)/// Visitor controls the traversal by returning ETreeTraverseCode////// @sa ETreeTraverseCode///template<class TTreeNode, class Fun>Fun TreeDepthFirstTraverse(TTreeNode& tree_node, Fun func){    int delta_level = 0;    ETreeTraverseCode stop_scan;    stop_scan = func(tree_node, delta_level);    switch (stop_scan) {        case eTreeTraverseStop:        case eTreeTraverseStepOver:            return func;        case eTreeTraverse:            break;    }    if (stop_scan)        return func;    delta_level = 1;    TTreeNode* tr = &tree_node;    typedef typename TTreeNode::TNodeList_I TTreeNodeIterator;    TTreeNodeIterator it = tr->SubNodeBegin();    TTreeNodeIterator it_end = tr->SubNodeEnd();    if (it == it_end)        return func;    stack<TTreeNodeIterator> tree_stack;    while (true) {        tr = *it;        stop_scan = eTreeTraverse;        if (tr) {            stop_scan = func(*tr, delta_level);            switch (stop_scan) {                case eTreeTraverseStop:                    return func;                case eTreeTraverse:                case eTreeTraverseStepOver:                    break;            }        }        if ( (stop_scan != eTreeTraverseStepOver) &&             (delta_level >= 0) &&              (!tr->IsLeaf())) {  // sub-node, going down            tree_stack.push(it);            it = tr->SubNodeBegin();            it_end = tr->SubNodeEnd();            delta_level = 1;            continue;        }        ++it;        if (it == it_end) { // end of level, going up            if (tree_stack.empty()) {                break;            }            it = tree_stack.top();            tree_stack.pop();            tr = *it;            it_end = tr->GetParent()->SubNodeEnd();            delta_level = -1;            continue;        }        // same level         delta_level = 0;    } // while    func(tree_node, -1);    return func;

⌨️ 快捷键说明

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