• 数据结构开发(19):树的定义、操作、存储结构与实现


    0.目录

    1.树的定义与操作

    2.树的存储结构与实现

    3.小结

    1.树的定义与操作

    树是一种非线性的数据结构:

    • 树是由 n ( n ≥ 0 ) 个结点组成的有限集合
      1. 如果 n = 0,称为空树;
      2. 如果 n > 0,则:

    树的示例:

    树中度的概念:

    • 树的结点包含一个数据及若干指向子树的分支
    • 结点拥有的子树数目称为结点的度
      1. 度为 0 的结点称为叶结点
      2. 度不为 0 的结点称为分支结点
    • 树的度定义为所有结点中度的最大值

    树的度示例:度为 3 的树

    树中的前驱后继

    • 结点的直接后继称为该结点的孩子
      1. 相应的,该结点称为孩子的双亲
    • 结点的孩子的孩子的......称为该结点的子孙
      1. 相应的,该结点称为子孙的祖先
    • 同一个双亲的孩子之间互称兄弟

    树的前驱和后继示例:

    树中结点的层次:

    • 根为第1层
    • 根的孩子为第2层
    • ......


    树中结点的最大层次称为树的深度或高度

    树的有序性:

    • 如果树中结点的各子树从左向右是有次序的,子树间不能互换位置,则称该树为有序树,否则为无序树。

    森林的概念

    • 森林是由 n ( n ≥ 0 ) 棵互不相交的树组成的集合

    树的一些常用操作:

    • 将元素插入树中
    • 将元素从树中删除
    • 获取树的结点数
    • 获取树的高度
    • 获取树的度
    • 清空树中的元素
    • 。。。

    在程序中表现为一种特殊的数据类型:

    树中的结点也表现为一种特殊的数据类型:

    树与结点的类关系:

    在StLib中定义TreeNode类和Tree类:
    TreeNode.h

    #ifndef TREENODE_H
    #define TREENODE_H
    
    #include "Object.h"
    
    namespace StLib
    {
    
    template <typename T>
    class TreeNode : public Object
    {
    public:
        T value;
        TreeNode<T>* parent;
    
        TreeNode()
        {
            parent = NULL;
        }
    
        virtual ~TreeNode() = 0;
    };
    
    template <typename T>
    TreeNode<T>::~TreeNode()
    {
    
    }
    
    }
    
    #endif // TREENODE_H
    

    Tree.h

    #ifndef TREE_H
    #define TREE_H
    
    #include "TreeNode.h"
    #include "SharedPointer.h"
    
    namespace StLib
    {
    
    template <typename T>
    class Tree : public Object
    {
    protected:
        TreeNode<T>* m_root;
    public:
        Tree() { m_root = NULL; }
        virtual bool insert(TreeNode<T>* node) = 0;
        virtual bool insert(const T& value, TreeNode<T>* parent) = 0;
        virtual SharedPointer< Tree<T> > remove(const T& value) = 0;
        virtual SharedPointer< Tree<T> > remove(TreeNode<T>* node) = 0;
        virtual TreeNode<T>* find(const T& value) const = 0;
        virtual TreeNode<T>* find(TreeNode<T>* node) const = 0;
        virtual TreeNode<T>* root() const = 0;
        virtual int degree() const = 0;
        virtual int count() const = 0;
        virtual int height() const = 0;
        virtual void clear() = 0;
    };
    
    }
    
    #endif // TREE_H
    

    2.树的存储结构与实现

    本节目标:

    • 完成结点的存储结构设计

    设计要点:

    • GTree 为通用树结构,每个结点可以存在多个后继结点
    • GTreeNode 能够包含任意多指向后继结点的指针
    • 实现树结构的所有操作 ( 增,删,查,等 )

    GTreeNode 的设计与实现:

    GTree 的设计与实现:

    GTree ( 通用树结构 ) 的实现架构:

    在StLib中定义GTreeNode类和GTree类,搭建基本框架:
    GTreeNode.h

    #ifndef GTREENODE_H
    #define GTREENODE_H
    
    #include "TreeNode.h"
    #include "LinkList.h"
    
    namespace StLib
    {
    
    template <typename T>
    class GTreeNode : public TreeNode<T>
    {
    public:
        LinkList<GTreeNode<T>*> child;
    };
    
    }
    
    #endif // GTREENODE_H
    

    GTree.h

    #ifndef GTREE_H
    #define GTREE_H
    
    #include "Tree.h"
    #include "GTreeNode.h"
    
    namespace StLib
    {
    
    template <typename T>
    class GTree : public Tree<T>
    {
    public:
        bool insert(TreeNode<T>* node)
        {
            bool ret = true;
    
            return ret;
        }
    
        bool insert(const T& value, TreeNode<T>* parent)
        {
            bool ret = true;
    
            return ret;
        }
    
        SharedPointer< Tree<T> > remove(const T& value)
        {
            return NULL;
        }
    
        SharedPointer< Tree<T> > remove(TreeNode<T>* node)
        {
            return NULL;
        }
    
        GTreeNode<T>* find(const T& value) const
        {
            return NULL;
        }
    
        GTreeNode<T>* find(TreeNode<T>* node) const
        {
            return NULL;
        }
    
        GTreeNode<T>* root() const
        {
            return dynamic_cast<GTreeNode<T>*>(this->m_root);
        }
    
        int degree() const
        {
            return 0;
        }
    
        int count() const
        {
            return 0;
        }
    
        int height() const
        {
            return 0;
        }
    
        void clear()
        {
            this->m_root = NULL;
        }
    
        ~GTree()
        {
            clear();
        }
    };
    
    }
    
    #endif // GTREE_H
    

    问题:

    • 每个树结点中为什么包含指向前驱结点的指针?

    根结点 → 叶结点:非线性数据结构
    叶结点 → 根节点:线性数据结构 ( 链表 )

    3.小结

    • 树是一种非线性的数据结构
    • 结点拥有唯一前驱 ( 父结点 ) 和若干后继 ( 子结点 )
    • 树的结点包含一个数据及若干指其它结点的指针
    • 树与结点在程序中表现为特殊的数据类型
  • 相关阅读:
    Mongoose Schemas中定义日期以及timestamps选项的妙用
    如何用Linux的命令正确识别cpu的个数和核数【转】
    缓存算法
    使用pm2常见问题
    JavaScript 循环:如何处理 async/await
    常用的Linux操作
    Mysql数据库If语句的使用
    java解析邮箱中的邮件信息
    淘宝分布式数据层TDDL
    maven正式版本和快照版本的区别
  • 原文地址:https://www.cnblogs.com/PyLearn/p/10155865.html
Copyright © 2020-2023  润新知