数据结构——树


一、树的定义

树是n(n>=0)个结点的有限集,n=0时称为空树。任意一个非空树中

(1)有且仅有一个根结点

(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集𝑇1,𝑇2,……,𝑇m其中每一个集合本身又是一棵树,并称为根的子树

树的结点的分类:

树的结点包含一个数据元素及若干指向其子树的分支,结点拥有的子树称为结点的度(Degree)

叶结点:度为0的结点

跟结点和内部结点:度不为0

树的度:树内各结点的度的最大值

结点间的关系:

结点的子树的根称为该结点的孩子,相应的该结点称为孩子的双亲。

同一个双亲的孩子之间互称兄弟

结点的祖先是从根到该结点所经分支上的所有结点。如下图,对于H来说,D、B、A都是它的祖先

树的其他相关概念:

结点的层次:从根开始定义起,根为第一层,根的孩子为第二层。树中结点的最大层次称为树的深度或者高度。

森林是m(m>=0)棵互不相交树的集合

二、树的存储结构

双亲表示法

我们假设以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点在数组中的位置。

 其中data是数据域存储结点的数据信息,而parent 是指针域,存储该结点的双亲在数组中的下标

//树的双亲表示法结点结构定义
#define MAX_TREE_SIZE 100
typedef int TElemType;		//树结点的数据类型
typedef struct PTNode		//结点结构
{
	TElemType data;			//结点数据
	int parent;				//双亲位置
}PTNode;
typedef struct				//树结构
{
	PTNode nodes[MAX_TREE_SIZE];    //结点数组
	int r;							//根位置
	int n;							//结点个数
}PTree;

由于根结点是没有双亲的,所以约定根结点的位置域设置为-1

下标

data

parent

0

A

-1

1

B

0

2

C

0

3

D

1

4

E

2

5

F

2

6

G

3

7

H

3

8

I

3

9

J

4

这样的存储结构我们可以根据结点的parent,很容易找到它的双亲结点,所用的时间复杂度为O(1),直到parent等于-1时,表示找到根结点,如果我们要知道结点的孩子是什么,需要遍历整个结构才行

孩子表示法:

由于树中每个结点可能有多棵子树,可以考虑用多重链表,即每个结点有多个指针域,其中每个指针指向一棵子树的根结点,我们把这种方法叫做多重链表表示法,树的每个结点的度,也就是它的孩子的个数是不同的。所以可以设计两种方案来解决

方案一:指针域的个数等于树的度

这种方法对于树中各个结点的度相差很大时,显然是很浪费空间的,因为有很多的结点它的指针域是空的。如果各个结点度相差很小时,那就意味着开辟的空间被充分利用了。

方案二:每个结点指针域的个数等于该结点的度

我们需要专门取一个位置来存储结点指针域的个数

这种方法克服了浪费空间的缺点,对空间的利用率是很高了,但是由于各个结点的链表是不同的结构,加上要维护结点的度的数值,在运算上就会带来时间上的损耗。

有没有既可以减少空指针的浪费又能使结点结构相同的方法?

孩子表示法:

(1)把每个结点的孩子结点排列起来,以单链表作为存储结构,则n个结点有n个孩子链表,如果是叶子结点,则此链表为空

(2)然后n个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组中

//树的孩子表示法结构定义
#define MAX_TREE_SIZE 100
typedef struct CTnode		//孩子结点
{
	int child;
	struct CTnode* next;
}* ChilePtr;	
typedef struct				//表头结构
{
	TElemType data;
	ChilePtr firstchild;
}CTbox;
typedef struct				//树结构
{
	CTbox nodes[MAX_TREE_SIZE];		//结点数组
	int r;							//根位置
	int n;							//结点个数
}CTree;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值