数据结构笔记--树
树
本章总结
概念与定义
一、基本术语
1、结点的度:
结点的度指的是结点分支的个数
2、树的度:
选取所有结点中最大的度,就是树的度
3、叶子结点:
度为0的结点就是叶子结点,它位于树最深层,并且树只要非空,就一定存在叶子结点
4、分支结点:
度大于0的结点为分支结点,显然除了叶子结点之外的结点都为分支结点。
5、层次:
树是一个递归结构,所以也有层次这种概念,由层次也会引发出树的深度,就好像递归也有深度一样。结点的层次为从结点到根结点的路径中边的条数,并且认为根结点的层次为0,因为根结点到自身的路径中边的条数为0(但也有一些教科书假设根结点的层次为1,这个时候要注意书中相应的说明)
6、树的深度:
与树的度对应于结点的度一样,树的深度也是选取结点中的最大深度(或最大层次)
7、森林:
森林的概念和树的概念是密切联系的。森林就是彼此不相交的树的集合,树也可以看成是森林共有一个根结点后的结构
二、树的存储结构
1、 顺序存储
2、 链式存储
三、二叉树
1、树转化为二叉树
2、二叉树转化为树
3、二叉树的性质
4、两种特殊形态的二叉树
满二叉树
完全二叉树(性质很多很重要)
5、二叉树的存储
完全二叉树的顺序存储
非完全二叉树的顺序存储
二叉树的链式存储
4、创建二叉树的算法
二叉树遍历
一、层次遍历
1、顺序存储实现
2、链式存储实现(借助队列)
一、递归算法
1、先序遍历
2、中序遍历
3、后序遍历
4、三种递归遍历算法分析
三、非递归的二叉树遍历(栈)
1、思路
2、代码
三、非递归的二叉树遍历(改进)
经过第二次时出栈(先序与中序)
1、思路
2、伪代码
3、时间复杂度分析
4、代码
四、非递归的二叉树遍历(进一步改进)
右孩子为空的节点不需要进栈
1、思路
2、代码
五、二叉树递归算法的应用举例
1、求二叉树的深度
算法基本思想
代码
2、统计二叉树中叶子结点的个数
算法基本思想
注意:有两个出口!!!!!
代码
3、求二叉树中第k层结点的个数
代码
二叉树的重建
思路
为什么?
前序根在开头,可以确定根
后序根在最后,可以确定根
确定根以后,将其重中序找出。在根前面是左子树的集合,根后面是右子树的集合。这样就划分为了两个子树。
例子
代码
s1:先序序列
s2:中序序列
low—低端
high–高端
递归出口:如果低端大于高端了
线索二叉树
基本概念
一个n个结点的二叉树,有2n个指针域,有n-1个指针使用,所以有n+1个指针域为空
线索二叉树的生成
算法
代码
以下为第一步(建树):
上述代码解释:
标志域先全置为1,有结点就变为0
第一红句:把默认情况放进去
接下来递归调用左子树
第二红句:如果左不空,改为0
接下来递归调用右子树
第三红句:如果右不空,改为0
以下为第二步:(头节点加进去,加线索化)
上述代码解释:
pre:指向前驱(线索化函数调用的结果是pre指向最后一个结点)
左边部分:头结点生成+树的线索化
右边部分:线索化函数(本质上就是中序遍历,不过访问的形式由print改成了加线索)
线索二叉树的遍历
算法
代码
测试主函数
树、森林、森林与二叉树的转换
树的三种表示方法
一、双亲表示法
二、孩子链表表示法
三、树的二叉链表(孩子-兄弟)表示法
森林与二叉树的转换
树和森林的遍历
一、树的遍历
二、森林的遍历
哈夫曼树与哈夫曼编码
简介
哈夫曼树
一、术语介绍
二、构造哈夫曼树基本思想
三、构造哈夫曼树算法
eg
习惯性把较小的放在左边,较大的放在右边
哈夫曼编码
一、编码
二、译码
三、译码的唯一性问题
编程实现
PS:为方便计算,权值全换为整数(例如都乘100)
PS:*w 为整型数组,放权值
初始化后选最小的两个,只要parent不是0,说明已经用过了,不用再参与比较了