数据结构开发(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.小结

  • 树是一种非线性的数据结构
  • 结点拥有唯一前驱 ( 父结点 ) 和若干后继 ( 子结点 )
  • 树的结点包含一个数据及若干指其它结点的指针
  • 树与结点在程序中表现为特殊的数据类型
posted @ 2018-12-21 15:12  PyLearn  阅读(627)  评论(0编辑  收藏  举报