树和森林(定义,存储方法及向二叉树的相互转换)

树和森林的定义

树和二叉树一样,也是一种多层次的数据结构,并且树中每个结点可以存在多个分支,因此它的应用领域更广。

树是 n(n>=0) 个数据元素(结点)的有限集D,若D为空集则为空树,否则: (1), D中存在唯一的称为根的数据元素称为 root。(2), 当 n > 1时,其余结点可以分成 m 个互不相交的有限集,其中每个子集都符合树的定义,并成为 root 的子树。

关于二叉树的各个术语都可以类似的对树进行定义。由于树中子树个数没有限定,所以树还有一个新的术语——“树的度”。定义为一棵树中各结点度的最大值称为该树的度。(二叉树中结点的度最大为2)。

二叉树和树是两种不同的树形结构。在树中,上一层与下一层之间只有“父-子”的关系,没有严格的次序。而在二叉树中,存在“父-左子”和“父-右子”两种关系,并且必须分清是哪一种关系即严格的左右关系。一般情况下,在树种不讨论子树之间的次序关系,称为无序树;而在有些问题种需要明确序位关系,称为有序树

森林是 m(m>=0) 棵互不相交的树的集合。因此也可以将树定义成 n(n>=0) 个结点的有限集,若 n=0, 则为空树,否则,树由一个根结点和 m(m>=0) 棵树组成的森林构成,森林中的每棵树都是根的子树。

树和森林的存储结构

 树的结构不如二叉树规整,因为树中结点可能会有多个孩子,因此直接用多个链域表示父子关系的方式会有严重缺陷,即结点的大小难以确定,若按树的度来设定,则会产生大浪费,如果按照结点的度来设定,则整棵树的结构不统一。因此需要新的存储方法:

1.双亲表示法

树中的每个结点只有一个双亲,且根结点的双亲为空。利用这个特性可对树中每个结点附加一个指示双亲的指针,并将所有结点以顺序结构组织在一起。定义如下:

const int MAX_TREE_SIZE = 100;

//定义结点结构
typedef struct PTNode {
	char data;    //结点数据域
	int parent;    //双亲位置域
}PTNode;

//定义树结构
typedef struct {
	PTNode nodes[MAX_TREE_SIZE];
	int r, n;     //表示根节点的位置和结点个数
}PTree;

举例如下:

如果定义该树为 PTree T; 则树的根为T.nodes[r].data;

2,孩子链表表示法 

在树的孩子链表中,以单链表将所有双亲相同的孩子结点链接在一起,并将该链表的头指针和双亲构成一个结点,全部树的结点以顺序组织构成树结构。例图如下:

定义该结构如下:

const int MAX_TREE_SIZE = 100;

//孩子结点结构
typedef struct CTNode {
	int child;   //表示第几个孩子(同一个双亲下孩子的编号)
	struct CTNode *next;
}*ChildPtr;

//双亲结点结构  (双亲是相对的,每一个结点都可以是双亲)
typedef struct {
	char data;
	ChildPtr firstchild;  //孩子链的头指针
}CTBox;

//树结构
typedef struct {
	CTBox nodes[MAX_TREE_SIZE];
	int n, r;     //结点数和根节点位置
}Ctree;

 3,树的二叉链表(孩子-兄弟)表示法

类似于二叉树的二叉链表,将树结点中的两个指针域分别指向其“最左”孩子结点和“右兄弟”结点。如图:

孩子-兄弟链表中结点结构的说明如下:

typedef struct CSNode {
	char data;
	struct CSNode *fristchild, *nextsibling;
}CSNode, *CSTree;

 观察上图发现,以二叉链表为媒介可以建立树和二叉树之间的一个确定的对应关系。即二叉树和树之间可以进行相互转换:如下图表示由森林转成二叉树

 而由二叉树也可以转成森林:

只要牢记:左下方的是该结点的左孩子,右下方的是该结点的右兄弟。 

本笔记所依据的教材为严薇敏版的《数据结构及应用算法教程》

部分图片来源于华中师范大学云课堂

所有代码在Visual Studio 2017上均可正常运行

如有错误欢迎指出

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值