• 一般树实现


        这里用C++实现了一个一般树,也就是那种通用型的树,例如文件系统所用的树。除了一些树的基本操作外,还支持了节点和数据项的迭代器。

        实现:

    #ifndef GENERAL_TREE_H
    #define GENERAL_TREE_H

    #include
    <stdlib.h>
    #include
    <string>

    template
    <typename Object>
    struct TreeNode
    {
    Object element;
    TreeNode
    *parent;
    TreeNode
    *firstChild;
    TreeNode
    *nextSibling;
    };

    template
    <class T>
    class GeneralIterator
    {
    public:
    virtual T* Next() = 0;
    virtual void Reset() = 0;
    };

    template
    <typename Object>
    class GeneralTree
    {
    public:
    /** Constructor **/
    GeneralTree();
    GeneralTree(
    const Object& rootElement);
    ~GeneralTree();

    /** Get node operations **/
    const TreeNode<Object>* GetRoot() const;
    TreeNode
    <Object>* GetRoot();
    const TreeNode<Object>* GetParent(const TreeNode<Object>* v) const;

    /** Iterators **/
    GeneralIterator
    <Object>* ElementsIterator();
    GeneralIterator
    < TreeNode<Object> >* NodesIterator();

    /** Check the node type **/
    bool IsInternal(const TreeNode<Object>* v) const;
    bool IsExternal(const TreeNode<Object>* v) const;
    bool IsRoot(const TreeNode<Object>* v) const;

    /** Get node count **/
    int Size() const;

    /** Elements operations **/
    void SwapElement(TreeNode<Object>* v, TreeNode<Object>* w);
    void SetElement(TreeNode<Object>* v, const Object& element);

    /** Node operations **/
    TreeNode
    <Object>* Insert(TreeNode<Object>* parent, const Object& element);
    TreeNode
    <Object>* InsertAfter(TreeNode<Object>* previousSibling,
    const Object& element);
    void Remove(TreeNode<Object>* v);
    void Remove(const Object& element);
    TreeNode
    <Object>* Find(const Object& element);

    int GetHeight(const TreeNode<Object>* v) const;
    int GetDepth(const TreeNode<Object>* v) const;

    /** traversal **/
    //param is used to pass in parameters and store results
    //the boolean returned value indicates if the traversal is done
    typedef bool (*Action)(TreeNode<Object>* v, void* param);
    bool PreorderTraversal(Action action,
    void* param=NULL, TreeNode<Object>* pNode=NULL);
    bool PostorderTraversal(Action action,
    void* param=NULL, TreeNode<Object>* pNode=NULL);
    private:
    TreeNode
    <Object>* _root;
    int _count;
    };

    template
    <typename Object>
    TreeNode
    <Object>* CreateEmptyNode(const Object* pElement)
    {
    TreeNode
    <Object>* pNode = new TreeNode<Object>();
    if(pElement != NULL) pNode->element = *pElement;
    pNode
    ->firstChild = NULL;
    pNode
    ->parent = NULL;
    pNode
    ->nextSibling = NULL;
    return pNode;
    }

    template
    <typename Object>
    GeneralTree
    <Object>::GeneralTree()
    {
    this->_root = CreateEmptyNode<Object>(NULL);
    this->_count = 1;
    }

    template
    <typename Object>
    GeneralTree
    <Object>::GeneralTree(const Object& rootElement)
    {
    this->_root = CreateEmptyNode<Object>(&rootElement);
    this->_count = 1;
    }

    template
    <typename Object>
    GeneralTree
    <Object>::~GeneralTree()
    {
    this->Remove(this->_root);
    }

    template
    <typename Object>
    inline
    const TreeNode<Object>* GeneralTree<Object>::GetRoot() const
    {
    return this->_root;
    }

    template
    <typename Object>
    inline TreeNode
    <Object>* GeneralTree<Object>::GetRoot()
    {
    return this->_root;
    }

    template
    <typename Object>
    inline
    const TreeNode<Object>* GeneralTree<Object>::GetParent(const TreeNode<Object>* v) const
    {
    return v->parent;
    }

    template
    <typename Object>
    class ElementsIterator : public GeneralIterator<Object>
    {
    public:
    ElementsIterator(GeneralTree
    <Object>* tree)
    {
    _current
    = -1;
    _count
    = tree->Size();
    _elements
    = new Object*[_count];
    this->FillPointers(tree);
    _current
    = -1;
    }
    ~ElementsIterator()
    {
    delete _elements;
    }

    Object
    * Next()
    {
    ++_current;
    if(_current < _count)
    return _elements[_current];
    else
    return NULL;
    }
    void Reset()
    {
    _current
    = -1;
    }
    private:
    Object
    ** _elements;
    int _current;
    int _count;

    void FillPointers(GeneralTree<Object>* tree);

    //friend functions
    template<typename T>
    friend
    bool AddPointer(TreeNode<T>* v, void* param);
    };

    template
    <typename T>
    bool AddPointer(TreeNode<T>* v, void* param)
    {
    ElementsIterator
    <T>* itr = (ElementsIterator<T>*)param;
    ++(itr->_current);
    (itr
    ->_elements)[itr->_current] = &(v->element);

    return false;
    }

    template
    <typename Object>
    void ElementsIterator<Object>::FillPointers(GeneralTree<Object>* tree)
    {
    tree
    ->PreorderTraversal(AddPointer,this);
    }

    template
    <typename Object>
    GeneralIterator
    <Object>* GetElementsIterator(GeneralTree<Object>* tree)
    {
    return new ElementsIterator<Object>(tree);
    }

    template
    <typename Object>
    GeneralIterator
    <Object>* GeneralTree<Object>::ElementsIterator()
    {
    return GetElementsIterator<Object>(this);
    }

    template
    <typename Object>
    class NodesIterator : public GeneralIterator< TreeNode<Object> >
    {
    public:
    NodesIterator(GeneralTree
    <Object>* tree)
    {
    _current
    = -1;
    _count
    = tree->Size();
    _elements
    = new TreeNode<Object>*[_count];
    this->FillPointers(tree);
    _current
    = -1;
    }
    ~NodesIterator()
    {
    delete _elements;
    }

    TreeNode
    <Object>* Next()
    {
    ++_current;
    if(_current < _count)
    return _elements[_current];
    else
    return NULL;
    }
    void Reset()
    {
    _current
    = -1;
    }
    private:
    TreeNode
    <Object>** _elements;
    int _current;
    int _count;

    void FillPointers(GeneralTree<Object>* tree);

    // friend functions
    template<typename T>
    friend
    bool AddNodePointer(TreeNode<T>* v, void* param);
    };

    template
    <typename T>
    bool AddNodePointer(TreeNode<T>* v, void* param)
    {
    NodesIterator
    <T>* itr = (NodesIterator<T>*)param;
    ++(itr->_current);
    (itr
    ->_elements)[itr->_current] = v;

    return false;
    }
    template
    <typename Object>
    void NodesIterator<Object>::FillPointers(GeneralTree<Object>* tree)
    {
    tree
    ->PreorderTraversal(AddNodePointer,this);
    }

    template
    <typename Object>
    GeneralIterator
    < TreeNode<Object> >* GetNodesIterator(GeneralTree<Object>* tree)
    {
    return new NodesIterator<Object>(tree);
    }

    template
    <typename Object>
    GeneralIterator
    < TreeNode<Object> >* GeneralTree<Object>::NodesIterator()
    {
    return GetNodesIterator<Object>(this);
    }

    template
    <typename Object>
    inline
    bool GeneralTree<Object>::IsInternal(const TreeNode<Object>* v) const
    {
    return v->firstChild != NULL;
    }

    template
    <typename Object>
    inline
    bool GeneralTree<Object>::IsExternal(const TreeNode<Object>* v) const
    {
    return v->firstChild == NULL;
    }

    template
    <typename Object>
    inline
    bool GeneralTree<Object>::IsRoot(const TreeNode<Object>* v) const
    {
    return v->parent == NULL;
    }

    template
    <typename Object>
    inline
    int GeneralTree<Object>::Size() const
    {
    return this->_count;
    }

    template
    <typename Object>
    void GeneralTree<Object>::SwapElement(TreeNode<Object>* v, TreeNode<Object>* w)
    {
    Object tem
    = v->element;
    v
    ->element = w->element;
    w
    ->element = tem;
    }

    template
    <typename Object>
    void GeneralTree<Object>::SetElement(TreeNode<Object>* v, const Object& element)
    {
    v
    ->element = element;
    }

    template
    <typename Object>
    TreeNode
    <Object>* GeneralTree<Object>::Insert(TreeNode<Object>* parent, const Object& element)
    {
    // Create the new node
    TreeNode<Object>* pNewNode = new TreeNode<Object>();
    pNewNode
    ->element = element;
    pNewNode
    ->parent = parent;
    pNewNode
    ->firstChild = NULL;
    pNewNode
    ->nextSibling = NULL;

    // Insert the new node
    if(parent->firstChild == NULL)
    {
    parent
    ->firstChild = pNewNode;
    }
    else
    {
    TreeNode
    <Object>* pChild = parent->firstChild;
    while(pChild->nextSibling != NULL) pChild = pChild->nextSibling;
    pChild
    ->nextSibling = pNewNode;
    }

    // increment the count
    ++this->_count;

    return pNewNode;
    }

    template
    <typename Object>
    TreeNode
    <Object>* GeneralTree<Object>::InsertAfter(TreeNode<Object>* previousSibling,
    const Object& element)
    {
    // Create the new node
    TreeNode<Object>* pNewNode = new TreeNode<Object>();
    pNewNode
    ->element = element;
    pNewNode
    ->parent = previousSibling->parent;
    pNewNode
    ->firstChild = NULL;

    // Connect new node with its previous node
    pNewNode->nextSibling = previousSibling->nextSibling;
    previousSibling
    ->nextSibling = pNewNode;

    // Increment the count
    ++this->_count;

    return pNewNode;
    }

    template
    <typename Object>
    bool FreeNode(TreeNode<Object>* v, void* param)
    {
    int* size = (int*)param;
    --(*size);
    delete v;
    return false;
    }

    template
    <typename Object>
    void GeneralTree<Object>::Remove(TreeNode<Object>* v)
    {
    if(v->parent != NULL)
    {
    // find the previous sibling
    TreeNode<Object>* pChild = (v->parent)->firstChild;
    if(pChild == v)
    v
    ->parent->firstChild = NULL;
    else
    {
    while(pChild->nextSibling != v) pChild = pChild->nextSibling;

    // adjust the tree structure
    pChild->nextSibling = v->nextSibling;
    }

    // free all the children and itself
    }
    this->PostorderTraversal(FreeNode,&(this->_count),v);
    }

    template
    <typename Object>
    void GeneralTree<Object>::Remove(const Object& element)
    {
    TreeNode
    <Object>* pRemovedNode = Find(element);
    this->Remove(pRemovedNode);
    }

    template
    <typename Object>
    struct TestParam
    {
    Object
    * pElement;
    TreeNode
    <Object>* pNode;
    };

    template
    <typename Object>
    bool TestElement(TreeNode<Object>* v, void* param)
    {
    // the param is an array,
    // in which the first element stores the pointer to the element
    // and the second element will store the pointer to the found node
    TestParam<Object>* pTestParam = (TestParam<Object>*)param;
    Object
    * pElement = pTestParam->pElement;
    if(v->element == *pElement)
    {
    pTestParam
    ->pNode = v; // set the found node
    return true; // it is done.
    }
    else
    return false;
    }

    template
    <typename Object>
    TreeNode
    <Object>* GeneralTree<Object>::Find(const Object& element)
    {
    Object findingElement
    = element;
    TestParam
    <Object> testParam;
    testParam.pElement
    = &findingElement;
    this->PreorderTraversal(TestElement, &testParam);
    return testParam.pNode;
    }

    template
    <typename Object>
    int GeneralTree<Object>::GetHeight(const TreeNode<Object>* v) const
    {
    if(this->IsExternal(v))
    return 0;
    else
    {
    int maxChildHeight = 0;
    TreeNode
    <Object> pChild = v->firstChild;
    while(pChild != NULL)
    {
    int childHeight = this->GetHeight(pChild);
    if(childHeight > maxChildHeight)
    maxChildHeight
    = childHeight;
    }
    return maxChildHeight + 1;
    }
    }

    template
    <typename Object>
    int GeneralTree<Object>::GetDepth(const TreeNode<Object>* v) const
    {
    if(this->IsRoot(v))
    return 0;
    else
    return 1 + this->GetDepth(v->parent);
    }

    template
    <typename Object>
    bool GeneralTree<Object>::PreorderTraversal(Action action,
    void* param, TreeNode<Object>* pNode)
    {
    if(pNode == NULL) pNode = this->_root;
    // visit the node
    bool isDone = action(pNode, param);
    if(isDone == false)
    {
    // traverse the children
    TreeNode<Object>* pChild = pNode->firstChild;
    while(pChild != NULL)
    {
    bool isDone = this->PreorderTraversal(action,
    param, pChild);
    if(isDone)
    break;
    else
    pChild
    = pChild->nextSibling;
    }
    }
    return isDone;
    }

    template
    <typename Object>
    bool GeneralTree<Object>::PostorderTraversal(Action action,
    void* param, TreeNode<Object>* pNode)
    {
    if(pNode == NULL) pNode = this->_root;

    // traverse the children
    TreeNode<Object>* pChild = pNode->firstChild;
    while(pChild != NULL)
    {
    bool isChildDone = this->PostorderTraversal(action, param, pChild);
    if(isChildDone)
    return true;
    else
    pChild
    = pChild->nextSibling;
    }

    // visit the element
    return action(pNode, param);
    }

    #endif
     

        测试代码:
        

    代码
    #include<iostream>
    #include
    <string>
    #include
    "GeneralTree.h"

    using namespace std;

    bool display(TreeNode<string>* v, void* param)
    {
    GeneralTree
    <string>* tree = (GeneralTree<string>*)param;
    int depth = tree->GetDepth(v);
    string prefix = "";
    for(int i = 0; i < depth; i++) prefix += "----";
    cout
    << prefix << v->element << endl;
    return false;
    }

    bool addPrefix(TreeNode<string>* v, void* param)
    {
    string* pStr = (string*)param;
    v
    ->element = *pStr + v->element;
    return false;
    }

    int main()
    {
    // construct the tree
    GeneralTree<string> tree("Paper");

    TreeNode
    <string>* insertedNode = tree.Insert(tree.GetRoot(), "Title");

    insertedNode
    = tree.InsertAfter(insertedNode, "Abstract");

    insertedNode
    = tree.InsertAfter(insertedNode, "$1");
    TreeNode
    <string>* insertedChild = tree.Insert(insertedNode, "$1.1");
    insertedChild
    = tree.InsertAfter(insertedChild, "$1.2");

    insertedNode
    = tree.InsertAfter(insertedNode, "$2");
    insertedChild
    = tree.Insert(insertedNode, "$2.1");
    insertedChild
    = tree.InsertAfter(insertedChild, "$2.2");
    insertedChild
    = tree.InsertAfter(insertedChild, "$2.3");

    insertedNode
    = tree.InsertAfter(insertedNode, "$3");
    insertedChild
    = tree.Insert(insertedNode, "$3.1");
    insertedChild
    = tree.InsertAfter(insertedChild, "$3.2");

    insertedNode
    = tree.InsertAfter(insertedNode, "References");

    // display the tree
    cout << "Preorder traversal:" << endl;
    tree.PreorderTraversal(display,
    &tree);

    cout
    << "Postorder traversal:" << endl;
    tree.PostorderTraversal(display,
    &tree);

    // edit the element
    TreeNode<string>* pFoundNode = tree.Find("$3");
    tree.SetElement(pFoundNode,
    "$3 cource");
    tree.SwapElement(tree.Find(
    "$3.1"),tree.Find("$3.2"));
    tree.Remove(
    "$1");
    cout
    << "after altering the elements" << endl;
    tree.PreorderTraversal(display,
    &tree);

    // test the node
    cout << "check if internal:" << (tree.IsInternal(pFoundNode)?"true":"false") << endl;
    cout
    << "check if external:" << (tree.IsExternal(pFoundNode)?"true":"false") << endl;
    cout
    << "check if root:" << (tree.IsRoot(pFoundNode)?"true":"false") << endl;
    cout
    << "size:" << tree.Size() << endl;

    // Iterator
    cout << "Traverse elements:" << endl;
    GeneralIterator
    <string>* itr = tree.ElementsIterator();
    string* pStr;
    while((pStr = itr->Next()) != NULL) cout << *pStr << endl;
    delete itr;

    cout
    << "Traverse nodes:" << endl;
    GeneralIterator
    < TreeNode<string> >* nodesItr = tree.NodesIterator();
    TreeNode
    <string>* pNode;
    while((pNode = nodesItr->Next()) != NULL)
    cout
    << "Node:" << string(4*tree.GetDepth(pNode),'-') << pNode->element <<endl;

    return 0;
    }

  • 相关阅读:
    linux 软件 手动添加至桌面或启动栏
    memcached 技术支持
    linux mint & ubuntu 安装QQ国际版
    2014总结
    http response 过长 导致Connection reset
    Python高质量缩放切图,抗锯齿
    eclipse使用Maven插件创建一个web project
    springMVC or response redirect https
    使用SharedPreference保存一些简单的信息
    手机的sd卡的写入和读取数据的方
  • 原文地址:https://www.cnblogs.com/alala666888/p/1906045.html
Copyright © 2020-2023  润新知