【数据结构】C++实现之树结构

1. 树的概念

1.1 树的定义
树(Tree)是由根结点和若干颗子树构成的。树是由一个集合以及在该集合上定义的一种关系构成的。集合中的元素称为树的结点,所定义的关系称为父子关系。父子关系在树的结点之间建立了一个层次结构。在这种层次结构中有一个结点具有特殊的地位,这个结点称为该树的根结点,或称为树根。n=0时称为空树。在任意一棵非空树中:
1)每个元素称为结点(node)
2)有一个特定的结点被称为根结点或树根(root)【唯一】
3)除根结点之外的其余数据元素被分为m(m≥0)个互不相交的集合T1,T2,……Tm-1,其中每一个集合Ti(1<=i<=m)本身也是一棵树,被称作原树的子树(subtree)【子树没有限制,但一定互不相交】
在这里插入图片描述
1.2 结点分类
树的结点包含-一个数据元素及若干指向其子树的分支。结点拥有的子树数称为结点的度(Degree)。度为0的结点称为叶结点(Leaf)或终端结点;度不为0的结点称为非终端结点或分支结点。除根结点之外,分支结点也称为内部结点。树的度是树内各结点的度的最大值。如图6-2-4所示,因为这棵树结点的度的最大值是结点D的度为3,所以树的度也为3。
在这里插入图片描述
1.3 其他相关概念
1)树结点的最大层次称为树的深度或高度如上(深度为4)
2)如果将树结点的各个子树看成从左至右是由次序的,这就是有序树,反之无序树。
3)森林m棵互不相交树的集合,【对于树的结点,其子树集合就是森林】
在这里插入图片描述

2. 树的抽象数据结构

在这里插入图片描述

3. 树的存储结构

前面介绍的所有的数据结构都是线性存储结构。本章所介绍的树结构是一种非线性存储结构,存储的是具有“一对多”关系的数据元素的集合。

3.1 双亲表示法
原理上还是利用一段连续的内存空间来存储树结构的数据,只是具体操作有些不同。它通过建立结点,每个结点内容如下:包含"数据域“与”指针域“,其中指针域作用是指向该节点的父节点位置。
在这里插入图片描述

//本质还是通过一段连续内存空间存储树结构数据
#define MAXSIZE 100
/*树的双亲表示法结点结构定义*/
typedef int ElemType;
struct  PTnode{
	ElemType data;  //结点数据
	int parent;		//双亲位置
};

struct PTree{
	PTnode node[MAXSIZE]; //结点数组
	int r, n;	//根的位置以及结点数
};

在这里插入图片描述
1)优点: 很容易找到结点的双亲,所用时间为O(1),直到parent=-1,即找到根节点为止
2)缺点:我们如果想找结点的孩子,则只有选择遍历整个树,时间O(n)
3)对于缺点我们有什么可以改进?如下我们可以增加个长子域【结点最左边孩子域】,如果没有孩子firstchild=-1。这样就解决有0或1个孩子的结点。而对于两个结点,我们已经知道一个,那么剩下的当然就是次子了。那要是我们又非常需要关注其兄弟间的关系,该怎么办? 那就增加一个兄弟域。
在这里插入图片描述
4)总之,这种数据结构十分灵活,对于我们非常关心的数据间关系(如父子,兄弟等等)可以通过灵活加域方式实现,同时加域多少取决于设计人的需求

3.2 孩子表示法
https://blog.csdn.net/shyjhyp11/article/details/72649863
http://data.biancheng.net/view/197.html
孩子表示法存储普通树采用的是 “顺序表+链表” 的组合结构,其存储过程是:从树的根节点开始,使用顺序表依次存储树中各个节点,需要注意的是,与双亲表示法不同,孩子表示法会给各个节点配备一个链表,用于存储各节点的孩子节点位于顺序表中的位置。
在这里插入图片描述

type int ElemType;
/*图3孩子表示法抽象数据类型*/
struct ChildNode{      
	ElemType child;		//孩子
	ChildNode *next;   //指针
};

typedef ChildNode *ChildNodeptr;  //指向孩子结点类型的指针

//孩子结点头部
struct ChildNodeHead{
	ElemType data;
	ChildNodeptr *firstchild;
};

struct Tree{
	ChildNodeHead nodes[MAXSIZE];
	int r, n;  //根位置(数据的起点)以及结点数
};

3.3 孩子兄弟表示法
孩子兄弟表示法,采用的是链式存储结构,其存储树的实现思想是:从树的根节点开始,依次用链表存储各个节点的孩子节点和兄弟节点。
在这里插入图片描述

//兄弟表示法
typedef int ElemType;
struct CSnode{
	ElemType data;   //结点数据
	CSnode *firstchild;
	CSnode *rightbother;
};

1)缺点:寻找结点父母不方便,解决方法,再加入一个指向父节点的指针
2)优点:这中方法最厉害的地方就是把一棵复杂的树转化为了“二叉树”结构,这样就可用二叉树特性与算法来处理它

发布了30 篇原创文章 · 获赞 6 · 访问量 5690

猜你喜欢

转载自blog.csdn.net/qq_32643313/article/details/105404989