树,二叉树,线索二叉树,霍夫曼树

本文详细介绍了树的概念、结点分类、存储结构,特别是双亲表示法、孩子表示法和孩子兄弟表示法。接着深入讲解了二叉树的定义、特点、特殊类型以及遍历方法,包括前序、中序、后序和层序遍历。此外,文章还讨论了线索二叉树的实现,如何利用空指针存储前驱和后继信息,以及树、森林与二叉树之间的转换。最后,提到了赫夫曼树的构造和应用,如赫夫曼编码,强调了其在数据传输优化中的作用。
摘要由CSDN通过智能技术生成

线性表,栈,队列等数据结构,他们有一个共同的特性,就是结构中每一个元素都是一对一的,可是在现实中,还有很多一对多的情况需要处理,所以我们需要研究这种一对多的数据结构 —— 树,并运用它的特性来解决我们在编程中遇到的问题。

一、树的定义

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

  (1)有且仅有一个特定的根结点

  (2)当n>1时,其余节点可分为m(m > 0)个互不相交的有限集T1,T2,.....,Tm,其中每一个集合又是一棵树,并且称为根的子树。如下图所示

 

注意:1,根节点是唯一的    2,子树的个数没有限制,但它们一定是互不相交的

2,结点分类

 

  (1)结点包含一个数据元素以及若干指向其子树的分支。

  (2)结点拥有的子树数量称为结点的度

  (3)度为0的结点称为叶节点或终端节点

  (4)度不为0的结点称为非终端结点或分支结点

  (5)一棵树的度是树内各节点的度的最大值

3,结点间的关系

  结点的子树的根称为该结点的孩子,该结点称为孩子的双亲。同一个双亲的孩子之间互称兄弟。结点的祖先是从根到该结点所经分支上的所有结点。反之,以某结点为根的子树中的任一结点都成为该结点的子孙。

4,树的其他相关概念

  (1)结点的层次从根开始定义,根为第一层,根的孩子为第二层,以此类推。

  (2)其双亲在同一层的结点互为表兄弟

  (3)树中结点的最大层次称为树的深度或高度

  (4)如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称该树为有序树,否则称为无序树。

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

二、树的存储结构

  我们介绍三种不同的表示方法:双亲表示法、孩子表示法、孩子兄弟表示法。

  1,双亲表示法

  结点可能没有孩子,但一定有双亲。假设我们以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点在数组中的位置。由于根节点没有双亲,所以我们约定根节点的位置域设为-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)。但如果我们要知道结点的孩子呢?对不起,请遍历整个结构才行。那么能不能改进一下呢?

我们增加一个结点最左边孩子的域,不妨叫他长子域,这样很容易得到结点的孩子。如果没有孩子的叶结点,这个长子域就设为-1,如下表

下标 data parent firstchild
0 A -1 1
1 B 0 3
2 C 0 4
3 D 1 6
4 E 2 9
5 F 2 -1
6 G 3 -1
7 H 3 -1
8 I 3 -1
9 J 4 -1

另外一个问题场景,我们关注各兄弟之间的关系,双亲表示法无法体现这样的关系,怎么办呢?可以增加一个右兄弟域来体现兄弟关系,也就是说,每一个结点如果它存在右兄弟,就记录下右兄弟的下标,同样的如果右兄弟不存在,就赋值为-1.

下标 data parent rightsib
0 A -1 -1
1 B 0 2
2 C 0 -1
3 D 1 -1
4 E 2 5
5 F 2 -1
6 G 3 7
7 H 3 8
8 I 3 -1
9 J 4 -1

如果节点的孩子很多,超过了两个,我们又关注节点的双亲,又关注节点的孩子,还关注结点的兄弟,而且还对时间遍历要求高,那么我们可以把此结构扩展为有各个域都包含。存储结构的设计是一个非常灵活的过程,一个存储结构设计的是否合理,取决于基于改存储结构的运算是否适合、是否方便,时间复杂度好不好等。

2,孩子表示法

 现在我们换一种不同的考虑方法。由于树中每个结点可能有多棵子树,可以考虑用多重链表即每个节点有多个指针域,其中每个指针指向一棵子树的根节点,我们把这种方法叫做多重链表表示法。

不过,树的每个结点的度,也就是孩子的个数是不同的,所以设计两种方案来解决。

方案一

  第一种方案是指针域的个数等于树的度。

 

 

   对于上面作为示例的树来说,度是3

 

 

 这种方法对于树中结点度相差很大时,是浪费空间的。

方案二

  每个结点指针域的个数等于该结点的度,专门取宇哥位置来存储结点指针域的个数,结构如下

 

 

 这种方案克服了空间浪费的缺陷,但由于每个结点的链表不同,加上要维护结点的度的值,在运算上会有时间上的损耗。

为了同时满足空间不浪费,又使节点结构相同,我们引出 —— 孩子表示法。 把每个节点的孩子结点排列起来,以单链表作为存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为空。然后n个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组。为了快速找到某个结点的双亲,我们把双亲表示法和孩子表示法综合一下如下图。

 

<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值