数据结构:树和二叉树

树结构是一种非线性结构,该结构中一个数据元素可以有两个或两个以上的直接后继元素,可以用来描述客观世界中广泛存在的层次关系。

1、 树的基本概念

在这里插入图片描述

树是 n(n>0)个结点的有限集合。当 n=0 时称为空树。在任一非空树(n>0)中,有且仅有个称为根的结点;其余结点可分为 m(m>0)个互不相交的有限集 T 1 , T 2 , … , T m T_1,T_2,…,T_m T1T2Tm,其中每个集合又都是一棵树,并且称为根结点的子树。

树的定义是逆归的,它表明了树本身的固有特性,也就是一棵树由若干棵子树构成,而子树又由更小的子树构成。

  1. 双亲、孩子和兄弟。结点的子树的根称为该结点的孩子,该结点称为其子结点的双亲。具有相同双亲的结点互为兄弟。
  2. 结点的度:一个结点的子树的个数记为该结点的度。
  3. 叶子结点:也称为终端结点,值度为零的结点。
  4. 内部结点:度不为零的结点称为分支结点或非终端结点。
  5. 结点的层次:根为第一层,根的孩子为第二层,依次类推。
  6. 树的高度:一棵树的最大层数记为树的高度(或深度)。
  7. 有序(无序)树:若将树中结点的各子树看成是从左到右有次序关系,即不能交换次序,则称该树为有序树,否则为无序树。
  8. 森林:是m( m ≥ 0 m\ge0 m0)棵互不相交的树的集合。

2、 二叉树

二叉树是 n(n≥0)个结点的有限集合,它或者是空树(n=0),或者是由一个根结点及两棵不相交的、分别称为左子树和右子树的二叉树所组成。
二叉树和普通树的区别:

  1. 二叉树的度最大为2,而普通树的度可以为任意正整数;
  2. 二叉树中结点的子树必须要分为左子树和右子树,而普通树不做区分。
    在这里插入图片描述

2.1 性质

  1. 性质1:二叉树第i层( i ≥ 1 i\ge1 i1)上至多有 i i − 1 i^{i-1} ii1个结点:。
  2. 性质2:深度为k的二叉树至多有 2 k − 1 2^k-1 2k1个结点( k ≥ 1 k\ge1 k1)。
  3. 性质3:对任何一棵二叉树,若其终端结点(叶子)数为n0,度为2的结点数为n2,则n0=n2+1。

2.2 满二叉树和完全二叉树

满二叉树:若深度为k的二叉树有 2 k − 1 2^k-1 2k1个结点。可以对其进行编号,从上到下,从左到右进行编号。编号为i的结点的左孩子编号为 2i、右孩子编号为 2i+1。

完全二叉树:深度为k、有‘n’个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号为 1~n 的结点一一对应。在一个高度为h的完全二叉树中,除了第h层(即最后一层),其余各层都是满的。在第h层上的结点必须从左到右依次放置,不能留空。
在这里插入图片描述
与满二叉树对应有空缺的二叉树称为不完全二叉树
在这里插入图片描述

2.3 存储结构

  1. 顺序存储
    用一组地址连续的存储单元存储二叉树中的结点时,必须将树中的结点排成一个适当的线性序列,并且结点在这个序列中的相互位置能反映出结点之间的逻辑关系。
    在这里插入图片描述
    顺序存储结构对完全二叉树而言既简单又节省空间,而对于一般二叉树则不适用。因为在顺序存储结构中,以结点在存储单元中的位置来表示结点之间的关系,因此对于一般的又树来说,也必须按照完全二叉树的形式存储,也就是要添上一些实际并不存在的“虚结点”这将造成空间的浪费。

  2. 链式存储
    采用三叉链表或者二叉链表。
    在这里插入图片描述

typedef struct BiTnode{
	char data;               /*结点的数据域*/
	struct BiTnode *lchild, *rchild;  /*左孩子指针域和右孩子指针域*/
}BiTnode, *BiTree;

2.3 二叉树遍历(利用递归函数实现)

遍历是按某种策略访问树中的所有结点,且对每个结点仅访问一次的过程。
由于二叉树所具有的递归性质,一棵非空的二叉树可以看作是由根结点、左子树和右子树三部分构成,因此若能依次遍历这三部分的信息,也就遍历了整棵二又树。按照遍历左子树要在遍历右子树之前进行的约定,依据访问根结点位置的不同,可得到二叉树的先序、中序和后序3 种遍历方法。

先序遍历二叉树的操作定义如下。若二叉树为空,则进行空操作。否则:

  1. 访问根结点。
  2. 先序遍历根的左子树
  3. 先序遍历根的右子树

中序遍历二叉树的操作定义如下。若二叉树为空,则进行空操作。否则:

  1. 中序遍历根的左子树。
  2. 访问根结点
  3. 中序遍历根的右子树

实际上,将中序遍历算法中对根结点的访问操作放在右子树的遍历之后,就得到后序遍历算法。遍历二叉树的过程实质上是按一定规则,将树中的结点排成一个线性序列的过程。

3 树和森林

可采用孩子兄弟表示法(又称为二叉链表表示法)来表示树(或森林),也就是在链表的结点中设置两个指针域,分别指向当前结点的第一个孩子结点和下一个兄弟结点。树的孩子兄弟表示法为实现树、森林与二叉树的相互转换莫定了基础。
在这里插入图片描述

3.1 树和森林与二叉树的相互转换

任何-个森林或一棵树可以对应一棵二叉树,而任一棵二叉树也能对应到一个森林或一棵树上。

  1. 树转化为二叉树:兄弟孩子表示法
    在这里插入图片描述

  2. 将一个森林转换为一棵二叉树的方法是:先将森林中的每一棵树转换为二叉树,再将第二棵树作为第一棵树的右子树,第三棵树作为第二棵树的右子树,依此类推。
    在这里插入图片描述

  3. 二叉树转换为树(或森林)
    二叉树中结点的左孩子解释为父子关系,右孩子解释为兄弟关系,即可将二叉树转换为唯一的森林或树。
    在这里插入图片描述

3.2 树和森林的遍历

遍历树的方法:先根遍历和后根遍历。

  1. 树的先根遍历是先访问树的根结点,然后依次先根遍历根的各棵子树。对树的先根遍历等同于对转换所得的二又树进行先序遍历。
  2. 树的后根遍历是先依次后根遍历树根的各棵子树,然后访问树根结点。树的后根遍历等同于对转换所得的二叉树进行中序遍历。

森林的两种遍历的方法:

  1. 先序遍历森林:若森林非空,首先访问森林中第一棵树的根结点,其次先序遍历第一棵子树根结点的子树森林,最后先序遍历除第一棵树之外剩余的树所构成的森林。
  2. 中序遍历森林:若森林非空,首先中序遍历森林中第一棵树的子树森林,其次访问第棵树的根结点,最后中序遍历除第一棵树之外剩余的树所构成的森林。

4 最优二叉树

最优二叉树又称为哈夫曼树,是一类带权路径最短的树。最优二叉树是指权值为 w 1 , w 2 , . . . , w n w_1,w_2,...,w_n w1,w2,...,wn 的n个叶子结点的二叉树中带权路径长度最小的二又树。

路径长度:从树中一个结点到另一个结点之间的通路称为两个结点间的路径,该通路上分支数目为路径长度。

树的路径长度:从树根到每一个叶子之间的路径长度之和。

结点的带权路径长度:为从该结点到树根之间的路径长度与该结点权值的乘积。

  • 哈夫曼树的构造:
    在这里插入图片描述

  • 哈夫曼树的特点:

    1. 权重越大的叶结点越靠近根结点,权重越小的叶结点越远离根结点;
    2. 不存在度为1的结点,具有m个叶结点所构造的哈夫曼树公有2m-1个结点。
  • 哈夫曼树的应用:通信过程中的编码和译码。
    设有字符集{a,b,c,d,e}对应的权重集合为{0.25,0.30,0.12,0.25,0.08}.

    1. 编码
      在这里插入图片描述
      编码之后:字符a,b,c,d,e对应的编码是10,11,001,01,000.

    2. 译码
      译码时就从树根开始,若编码序列中当前位为0,则进入当前结点的左子树;为1则进入右子树,到达叶子结点时一个字符就翻译出来了,然后再从树根开始重复上述过程,直到编码序列结束。例如,若编码序列 101110000001对应的字符编码可翻译出字符序列"abaec"。

5 二叉查找树

二叉査找树又称为二叉排序树或二叉检索树,它或者是一棵空树,或者是具有如下性质的二叉树。

  1. 若它的左子树非空,则左子树中所有结点的值均小于根结点的值
  2. 若它的右子树非空,则右子中所有结点的值均大于根结点的值。
  3. 左、右子树也是二叉查找树。

在这里插入图片描述
二叉查找树是一种特殊的二叉树,数据库常用它来存储数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值