在树中通常将数据元素称为结点。

树是n个结点的有限集合。当n=0时,称为空树,任意一颗非空树满足以及条件:

1:有且仅有一个特定的称为根(root)的结点

2:当n>1时,除根结点之外的其余结点被分成m(m>0)个互不相交的有限集合T1,T2,…,Tn,

其中每个集合又是一棵树,并称为这个根结点的子树。

 

树的基本术语

结点的度,树的度

某结点所拥有的子树的个数称为该结点的度(degree);树中各结点度的最大值称为该树的度。

叶子结点、分支结点

度为0的结点称为叶子结点(leaf node),也称为终端结点;度不为0的结点称为分支结点(branch node),也称为非终端结点。

孩子结点、双亲结点、兄弟结点

某结点的子树的根结点称为该结点的孩子结点(child node);反之,该结点称为其孩子结点的双亲结点(parent node);具有同一个双亲的孩子结点互称为兄弟结点(brothe)。

路径、路径长度

如果树的结点序列n1,n2,…nk满足如下关系:结点ni是结点n(i+1)的双亲(1≤i<k)则n1n2…nk称为一条由n1至nk的路径(path);路径上经过的边数称为路径长度(h)。显然,在树中路径是唯一的。

祖先、子孙

如果从结点x到结点y有一条路径,那么x就称为y的祖先,y称为x的子孙。显然,以某结点为根的子树中的任一结点都是该结点的子孙。

结点的层数、树的深度(高度)、树的宽度

规定根结点的层数(level)为1,对其余任何结点,某结点在第k层,则其孩子结点在k+1层;树中所有结点的最大层数称为树的深度(depth),也称为树的高度。树中每一层结点个数的最大值称为树的宽度(breadth)。

 

树的遍历

树的遍历是指从根结点出发,按照某种次序访问树中所有的结点,使得每个结点被访问且只被访问一次。树的遍历次序通常有前序遍历,后序遍历,和层序遍历。

树的前序遍历操作:

若树为空,则空操作返回,否则执行以下操作

1 访问根结点

2 按照从左到右的顺序前序遍历根结点每一颗子树。

树的后序遍历操作:

若树为空,则空操作返回,否则执行以下操作

1 按照从左到右的顺序后序遍历根结点每一颗子树。

2 访问根结点

树的层次遍历操作:

从树的根结点开始,自上而下逐层遍历,在同一层中,按照从左到右的顺序对结点逐个访问。

 

树的存储结构

一:双亲表示法

template<typename T>

struct Node{

    T data;

    int parent;

};

存储思路:用一维数组来存储树的各个结点,数据元素包括树中结点的数据信息,以及该结点的双亲在数组中的下标。

二:孩子表示法

孩子表示法是基于链表的存储方法,把每个结点的孩子排列起来,看成一个线性表,且以单链表存储,称为该结点的孩子链表。假设有n个结点,也就有n个孩子链表,也就有n个头指针,这n个头指针又构成了一个线性表,采用顺序存储。将存放n个头指针的数组和存放n个结点信息的数据结合,构成孩子链表的表头数组。

struct CTNode{
    int child;//链表中每个结点存储的不是数据本身,而是数据在数组中存储的位置下标
    CTNode * next;
}
struct CBNode{
    T data;//结点的数据类型
    CTNode *firstchild;//孩子链表的头指针
}

无

三:孩子兄弟表示法

链表中的每个结点除数据域外,还设置了两个指针分别指向该结点的第一个孩子和右兄弟。

typedef struct CSNode{
    ElemType data;
    struct CSNode * firstchild,*nextsibling;
}

孩子兄弟表示法与单链表的相关算法类似,就不多叙述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值