第57课 - 树中属性操作的实现

1、树中结点的数目

         - 定义功能: count(node

                在node为根结点的树中统计结点数目


        树结点数目的计算示例

                    - count(A)= count(B)+ count(C)+ count(D)+1

        


2、树的高度

       -  定义功能: height(node)

                获取node为根结点的树的高度

        


                树的高度计算示例

                        - height(A)= MAX{ height(B), height(C), height(D) } + 1

    


3、树的度数

         -  定义功能: degree ( node)

                   获取node为根结点的树的度数

        

        树的度计算示例

                 - degree(a)= MAX{ degree(B), degree(C), degree(D),3 }




4、编程实验

#ifndef GTREE_H
#define GTREE_H

#include "Tree.h"
#include"GTreeNode.h"
#include"Exception.h"


namespace DTLib
{
template < typename T >
class GTree : public Tree<T>
{
protected:
    GTreeNode<T>* find(GTreeNode<T>* node,const T& value) const
    {
        GTreeNode<T>* ret = NULL;

        if(node != NULL)
        {
            if(node->value == value)
            {
                return node;
            }
            else
            {
                for(node->child.move(0);!node->child.end() && (ret == NULL);node->child.next())     //在node子树中查找
                {
                    ret = find(node->child.current(),value);    //child里数据元素类型是GTreeNode<T>*
                }
            }
        }

        return ret;
    }

    GTreeNode<T>* find(GTreeNode<T>* node,GTreeNode<T>* obj) const
    {
        GTreeNode<T>* ret = NULL;

        if(node == obj)
        {
            return node;
        }
        else
        {
            if(node != NULL)
            {
                for(node->child.move(0);!node->child.end() && (ret == NULL);node->child.next())
                {
                    ret = find(node->child.current(),obj);
                }
            }
        }

        return ret;
    }

    void free(GTreeNode<T>* node)
    {
        if(node != NULL)
        {
            for(node->child.move(0);!node->child.end();node->child.next())
            {
                free(node->child.current());
            }

            if(node->flag())
            {
                delete node;
            }

        }
    }

    void remove(GTreeNode<T>* node,GTree<T>*& ret)
    {
        ret = new GTree<T>();

        if(ret == NULL)
        {
            THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create new tree ...");
        }
        else
        {
            if( root() == node)    //待删结点就是跟结点
            {
                this->m_root = NULL;
            }
            else
            {
                LinkList< GTreeNode<T>* >& child = dynamic_cast< GTreeNode<T>* >(node->parent)->child; //child引用指向待删除结点父结点的链表

                child.remove(child.find(node)); //在父结点的链表中 将指向(结点的指针)待删孩子  的结点删除

                node->parent = NULL;    //此子树彻底地离开了树,并没有清除释放
            }

            ret->m_root = node;
        }
    }

    int count(GTreeNode<T>* node) const
    {
        int ret = 0;

        if(node != NULL)
        {
            ret = 1;    //如果node没有孩子for循环不会执行 返回1

            for(node->child.move(0);!node->child.end();node->child.next())
            {
                ret += count(node->child.current());
            }
        }

        return ret;   //如果node为空直接返回0
    }

    int height(GTreeNode<T>* node) const
    {
        int ret = 0;

        if(node != NULL)
        {
            for(node->child.move(0);!node->child.end();node->child.next())
            {
                int h = height(node->child.current());

                if(ret < h)
                {
                    ret = h;
                }
            }

            ret = ret + 1;
        }


        return ret;
    }

    int degree(GTreeNode<T>* node) const
    {
        int ret = 0;

        if(node != NULL)
        {
            ret = node->child.length(); //根结点的度

            for(node->child.move(0);!node->child.end();node->child.next())
            {
                int d = degree(node->child.current());  //每个孩子的度

                if(ret < d)     //拿根结点的度和其它结点度比较
                {
                    ret = d;
                }
            }
        }

        return ret;
    }

public:
    bool insert(TreeNode<T>* node)
    {
        bool ret = true;

        if(node != NULL)
        {
            if(this->m_root == NULL)
            {
                node->parent = NULL;
                this->m_root = node;
            }
            else
            {
                GTreeNode<T>* np = find(node->parent);

                if( np != NULL )
                {
                    GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);

                    if( np->child.find(n) < 0 )
                    {
                        np->child.insert(n);
                    }
                }
                else
                {
                    THROW_EXCEPTION(InvalidOperationException,"Invalid parent tree node ...");
                }
            }
        }
        else
        {
            THROW_EXCEPTION(InvalidParameterException,"Parameter node cannot be NULL ...");
        }

        return ret;
    }

    bool insert(const T& value,TreeNode<T>* parent)
    {
        bool ret = true;

        GTreeNode<T>* node = GTreeNode<T>::NewNode();

        if(node)
        {
            node->value = value;
            node->parent = parent;

            insert(node);
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create new tree node ...");
        }

        return ret;
    }

    SharedPointer< Tree<T> > remove(const T& value)
    {
        GTree<T>* ret = NULL;

        GTreeNode<T>* node = find(value);

        if(node == NULL)
        {
            THROW_EXCEPTION(InvalidParameterException,"Can not find the node via parameter value ...");
        }
        else
        {
            remove(node,ret);
        }


        return ret;
    }
    SharedPointer< Tree<T> > remove(TreeNode<T>* node)
    {
        GTree<T>* ret = NULL;

        node = find(node);

        if(node == NULL)
        {
            THROW_EXCEPTION(InvalidParameterException,"Parameter node is invalid ...");
        }
        else
        {
            remove(dynamic_cast<GTreeNode<T>*>(node),ret);
        }

        return NULL;
    }

    GTreeNode<T>* find(const T& value) const
    {
        return find(root(),value);
    }
    GTreeNode<T>* find(TreeNode<T>* node) const
    {
        return find(root(),dynamic_cast< GTreeNode<T>* >(node));
    }
    GTreeNode<T>* root() const
    {
        return dynamic_cast< GTreeNode<T>* >(this->m_root);
    }
    int degree() const
    {
        return degree(root());
    }
    int count() const
    {
        return count(root());
    }
    int height() const
    {
        return height(root());
    }
    void clear()
    {
        free(root());
        this->m_root = NULL;
    }

    ~GTree()
    {
        clear();
    }
};

}
#endif // GTREE_H

main.cpp

#include <iostream>
#include"GTree.h"

using namespace std;
using namespace DTLib;


int main()
{
    GTree<char> t;
    GTreeNode<char>* node = NULL;

    GTreeNode<char> root;

    root.value = 'A';
    root.parent = NULL;

    t.insert(&root);    //将局部对象作为根结点插入

    node = t.find('A');
    t.insert('B',node);
    t.insert('C',node);
    t.insert('D',node);

    node = t.find('B');
    t.insert('E',node);
    t.insert('F',node);

    node = t.find('E');
    t.insert('K',node);
    t.insert('L',node);

    node = t.find('C');
    t.insert('G',node);

    node = t.find('D');
    t.insert('H',node);
    t.insert('I',node);
    t.insert('J',node);

    node = t.find('H');
    t.insert('M',node);

    cout<<t.count()<<endl;
    cout<<t.height()<<endl;
    cout<<t.degree()<<endl;



    return 0;
}

                        


5、实战预告

        To be continued

        思考

                如何 遍历 GTree (通用树结构)的每一个结点?


猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/80473179
今日推荐