数据结构学习之第7章 树和二叉树

数据结构学习之第7章 树和二叉树

0x7.1.1 树的基本概念

 1.树的定义

​ 树是由n(n>=0)个结点(或元素)组成的有限集合(记为T)

​ 如果n>0,这n个结点中有且仅有一个结点作为树的根结点,简称为根,其余结点可分为m(m>=0)个互不相交的有限集\[T_{1}T_{2}\cdots T_{m}\],其中每个子集又是一棵符合定义的子树,称为根结点的子树。

知识点:由树的定义我们可以看出来树的结构是递归的

 2.树的逻辑表示法

​ 1.树形表示法

​ 2.文氏图表示法

​ 3.凹入表示法*

​ 4.括号表示法

0x7.1.2 树的基本术语

​ 1.结点的度与树的度:

​ 树中某个子结点的个数称为该结点的度,树中所有结点的度中最大值称为树的度,我们通常称树的度为m的树称为m次数。

​ 2.分支结点与叶子结点:

​ 树中度不为0的结点称之为非终端结点,分支结点,根据度的数目分为单分支、双分支、多分枝

​ 3.路径与路径长度:

​ 路径从i->j经过的点序列 \[k_{i}k_{i+1} \cdots k_{j} \]

​ 路径长度=路径上的分支数=点数-1

​ 4.孩子结点、双亲结点、兄弟结点

​ 孩子结点: 每个结点的后继结点

​ 兄弟结点: 具有同一双亲结点的孩子结点

​ 5.结点层次和树的高度

​ 跟结点开始算第一层,根结点的孩子结点算第二层,结点层次也可称为结点深度

​ 树中最大的结点层次称为树的高度。

​ 6.有序树和无序树

​ 有序树: 各结点的子树按照一定次序从左到右排序

​ 默认一般为有序树

​ 7.森林

​ n(n>0)互不相交的子树的集合称为森林

0x7.1.3 树的性质

性质1: 树中的结点数目等于所有结点的度数和+1

证明: 每个结点有且仅有一个前驱节点,这样结点与指向它的分支一一对应,也就是一个分支对应的一个结点,这样除开跟结点就有 分支数目等于结点数目,加上根结点就是, 所有结点的度数和+1 = 结点数目(缺少一度取指向根结点)

性质2: 对于度为m的树第i层的结点数最多为为\[m^{i-1}\]

证1: 归纳法

i=0 -> 1 正确

假设i-1层 为 \[m^{i-2}\] 个结点

有树的度的定义可知,每个结点的孩子结点为m,由此可得 i 层 为 \[m^{i-1}\]

性质3: 高度为h的m次树最多有\[\frac{m^h-1}{m-1}\]个结点

有性质2易得

\[m^{0}+m^{1} \cdots + m^{h-1} = \frac {m^{h}-1}{m-1} \]

由此可知满m次数的定义为: 满足性质3的时候是满m次数

性质4: 具有n个结点的m次树的最小高度为: \[log_m{(n(m-1)+1)}\]

例子: 3次数 n=20 -> \[\lceil log_3{41} \rceil\] = 4

最大高度的话: n-m+1

直线的话: n个点->n高度

常用的计算技巧:

结点的度数之和= \[n_{0}+n_{1}+2n_{2}+ \cdots + mn_{m}\] = n-

\[n_{0}+n_{1}+n_{2}+ \cdots + n_{m}\] = n

0x7.1.4 树的基本运算

 树的遍历:

1.先根遍历

​ (1)访问根结点

​ (2)按照从左到右的顺序依次先根遍历根结点的每一棵子树。(递归定义)

2.后根遍历

​ (1)按照从左到右的顺序依次先根遍历根结点的每一棵子树

​ (2)访问根结点

3.层次遍历

​ 从根结点开始从上到下、从左到右的次序访问树中的每一个结点。

7.1.5 树的存储结构

1.双亲存储结构

typedef struct
{
    ElemType data;
    int parent; //顺序存储
}PTree[MaxSize]; 

2.孩子链结构

typedef struct node
{
    ElemType data;
  struct node * sons[MaxSons];
}TSonNode;

3.孩子兄弟链

typedef struct node
{
  ElemType data;
  struct node * vp; //孩子结点
  struct node * bp; //兄弟结点
}TSBNode;

0x7.2 二叉树的概念和性质

7.2.1 二叉树的定义和树区别

​ 1.二叉树是一个有限的结点集合,这个集合或者为空,或者由一个根结点和两棵互不相交的称为左子树和右子树的二叉树组成。

​ 2.树与二叉树的区别

​ (1) 度为2的树中至少有一个结点的度为2,而二叉树没有这种要求。

​ (2)二叉树严格区分左右子树

​ 3.满二叉树的定义

​ (1)一棵二叉树中,如果所有分支结点都有左孩子结点和右孩子结点,并且所有叶子结点都集中在二叉树的最下一层。

​ (2)高度为h且二叉树最下一层的结点数为\[2^{h-1}\]

​ 4.非空满二叉树的特点:

​ (1)度为0或者度为2

​ (2)叶子结点都在最下一层

​ 5.完全二叉树的定义

​ 二叉树中只有最下面两层的结点的度数可以小于2,并且最下面一层的叶子结点都依次排列在该层最左边的位置上。

​ 6.非空完全二叉树的特点

>叶子结点只可能在最下面两层中出现
>
>对于最大层次中的叶子结点,都依次排列在左边
>
>如果有度为1的结点只可能有一个,且该结点只有左孩子
>
>按层序编号时,一旦出现编号i的结点是叶子结点或只有左孩子结点的,则编号大于i的结点均为叶子结点
>
>当结点总数n为奇数时,$$n_{1}$$=1,当为偶数时,$$n_{1}$$=0
0x7.2.2 二叉树的性质

性质1:

非空二叉树上叶子结点数等于双分支结点数目+1

证明: n=n0 + n1 + n2 = n1 + 2*n2 +1 => n0 = n2+1

总结下常用等式:

\[n = n_{0}+n_{1}+n_{2}=2n_{2}+n_{1}+1=所有结点的度+1\]

所有结点的度数之和 = \[2n_{2} + n_{1}\]

性质2: 非空二叉树的第i层上最多有\[2^{i-1}\]个结点。-> \[m^{i-1}\]

性质3: 高度为h的二叉树最多有 \[2^{h}-1\]个结点

性质4:

完全二叉树中层序编号为i的结点 若 i \[\leq \lfloor n/2 \rfloor \]\[2i \leq n\] 时为分支结点,否则为叶子结点。

若n为奇数,则每个分支结点有左孩子和右孩子,若n为偶数,则编号最大的分支结点只有左孩子结点,其余分支结点都有左右孩子

当 n=2 时满足

当 n=n-1 时 假设满足

其实原理很简单 \[2^{i}=2^{0}+ \cdots + 2^{i-1}\] 所以n/2 也就是倒数第2层 这是全都满的时候

编号为i的左孩子结点为 2i 右孩子结点为2i+1 双亲结点为: \[ \lfloor 2i\rfloor\]

性质5:

具有n个(n>0)结点的完全二叉树的高度为\[\lceil log_2{n+1} \rceil \]

7.2.3 二叉树与树、森林之间的转换

1.单棵树转换为二叉树转换规则

(1) 将树中所有相邻兄弟之间加一条连线

(2)将树中的每个结点只保留它与长子之间的连线,删除与其他孩子之间的联系

(3)以树的根结点为轴心,将整棵树顺时针旋转45度,使之结构层次分明。

2.森林转换为二叉树

(1)将单棵树按照1规则转换为二叉树

(2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的右孩子结点。

这个转换的思想:

其实就是将多出来的兄弟结点转换为右孩子。

1.二叉树转换为单棵树的转换规则

(1) 若某结点是其双亲的左孩子,则把该结点的右孩子、右孩子的右孩子等都与该结点的双亲结点用连线连起来

(2)删除原二叉树中所有双亲结点与右孩子结点之间的连线

(3)逆时针旋转45度,使之结构层次分明

7.2.4 二叉树的存储结构

1.顺序存储结构和链式存储结构

7.2.5 二叉树的基本运算

1.创建二叉树 CreateBTree(b,str)

2.销毁二叉树 DestroyBTree(&b);

3.查找结点 FindNode(b,x);

4.找孩子结点 LchildNode(p) RchildNode(p);

6.求高度 BTHeight(b);

7.输出二叉树DispBTree(b);

7.2.6 二叉树的遍历

1.定义

​ 二叉树遍历是指按照一定的次序访问二叉树中的所有结点,并且每个结点仅被访问一次的过程。

2.种类

 先序遍历:

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

 中序遍历

1.中序遍历左子树

2.访问根结点

3.中序遍历右子树

 后序遍历

1.访问左子树

2.访问右子树

3.访问根结点

 层次遍历

1.从左到右,一层一层地去遍历

7.2.7 二叉树的构造

定理7.1:

任何n(n>=0)个不同结点的二叉树,都可由它的中序序列和先序序列唯一地确定。

证明过程:

先序序列确定了根结点,中序序列确定了左右子树,

定理7.1:

任何n(n>=0)个不同结点的二叉树,都可由它的中序序列和后序序列唯一地确定。

证明过程:

后序序列确定了根结点,中序序列确定了左右子树,

7.2.8 线索二叉树

1.何为线索(thread):

规定当某结点的左指针为空时,令该指针指向这个线性序列中该结点的前驱结点,当某结点的右指针为空时,令该指针指向这个线性序列中该结点的后继结点,这样指向该序列的"前驱结点"、"后继结点"的指针称之为线索。

2.创建线索的过程称为线索化

3.线索化的二叉树称之为线索二叉树(threaded binary-tree)

注意:

为使创建线索二叉树的算法设计方便,在线索二叉树在增加一个头结点。头结点的data域为空,lchild指向无线索时的根结点,ltag=0,rchild指向按某种方式遍历二叉树时最后一个结点,rtag=1

7.2.9 哈夫曼树

结点的权:结点的值

带权路径长度: 从根结点到该结点之间的路径长度与该结点上的权的乘积(WPL weighted Path Length)

树的带权路径:

​ WPL = \[\sum_{i=1}^{n_{0}} w_{i}l_{i}\]

哈夫曼树(最优二叉树):

\[n_{0}\]个带权叶子结点的构成的所有二叉树中,带权路径长度WPL最小的二叉树

哈夫曼编码:

编码: 在数据通信中,将要发送的文字转换为二进制的0和1组成的二进制字符串。

实质: 使用频率越高的字符采用最短的编码

需要编码的字符集合为\[d_{1},d_{2} \dots ,d_{n}\],出现的频率为\[{w_{1},w_{2} \dots ,w_{n}}\],字符集合作为叶子结点,频率集合作为各根结点到每个叶子结点的权值构造一棵哈夫曼树,规定哈夫曼树的左分支为0,右分支为1,则从根结点到每个叶子结点所经过的分支对应的0和1组成的序列便是该结点对应字符的编码,这样的编码称之为哈夫曼编码。

7.2.10 并查集

定义:

n个不同的元素被分为若干组,每组是一个集合,这种集合叫分离集合,称之为并查集。

作用:

高效求解等价类问题

0x8 学习总结

​ 不知道最近自己到底在干嘛,感觉脑子真的不太好使,心里各种问题就像恶魔一样纠缠不清,每天都要花费将近\[\frac{5}{6}\]的精力去调节,留给学习的时间真的寥寥无几,效率对比以前真的特别低,就当作是一种平衡过去那种功利的心态的,每做一点实事都意味着自己迈出了一步,还是希望自己不要那么懒惰了,加把劲去学习。

猜你喜欢

转载自www.cnblogs.com/xq17dog/p/10854457.html