《数据结构复习》树
复习概要:
- 了解树的概念和基本术语
- 掌握二叉树的概念,性质,分类
- 掌握二叉树的存储结构和遍历方式
- 熟悉二叉树的创建
- 了解线索二叉树与哈夫曼数
1,树
1.1 什么是树
树是由n个结点组成的一个具有层次关系的有限集合。
树中相关的概念:根,结点,叶子,孩子结点,兄弟节点,祖先结点,度,树的高度。
1.2 树的表示法
1,图形表示法
图像表示法就是通常看到的由圈圈和线组成的数。
2,广义表表示法
如: (A(B(E,F,G),C(H),D(I,J)))
3,左孩子右兄弟表示法
结点的左边是节点的子结点,右边是节点的兄弟节点, 通常使用这种方法将树转化为二叉树
2,二叉树
2.1 什么是二叉树
二叉树具有两个基本的特征如下:
- 每个节点最多只能有两个孩子结点
- 二叉树是有序树,左子树和右子树次序不能颠倒,即使树中某个节点只有一颗子树,也要区分是左子树还是右子树。
2.2 二叉树的分类
根据二叉树中子节点的排布,可将二叉树分为非完全二叉树,完全二叉树和满二叉树。
2.3 二叉树的性质
- 在二叉树的第i层上至多有2^(i-1)个结点
- 深度为k的二叉树至多有2^k -1个结点
- 对于任何一颗二叉树,若度为2的结点数有n2个,则叶子节点数必定为n2+1个
- 具有n个节点的完全二叉树,它的深度必为[log2 n]+1
- 若对于完全二叉树中的节点从上至下,从左至右编号,则编号为i(1<=i<=n)的节点,其左孩子编号必为2i,其右孩子节点必为2i+1,其双亲编号必为i/2
3,二叉树的存储结构
3.1 二叉树的顺序存储
对于完全二叉树的顺序存储,可以根据角标推算出节点在二叉树中的位置。
对于一般二叉树的顺序存储,依据角标并不能推算出节点在二叉树中的位置,所以对于一般二叉树,存储方式是补全二叉树的顺序存储。
对于二叉树的顺序存储... 额 实际中并不会这样存储,因为太麻烦了,了解一下就好
3.2 二叉树的链式存储
1,二叉树链表示法
使用二叉链表示树,通常树中的每个节点由三部分组成:数据域和左,右指针域。
结点的类型定义如下:
typedef struct BitNode
{
DataType data;
struct BitNode *lchild,*rchild;
}BitNode;
typedef struct BitNode *BiTree;
2,三叉链表示法
使用三叉链表示法,树中的每个节点教二叉链表示法多了父节点的指针,
节点的类型定义如下:
typedef struct BitNode
{
DataType data;
struct BitNode *lchild,*rchild;
struct BitNode *parent;
}BitNode;
typedef struct BitNode *BiTree;
4,二叉树的遍历
遍历一颗二叉树有很多种方法。加入用D,L,R分别表示二叉树的根节点,左子树,右子树,那么要遍历这颗二叉树,方法就有6种:DLR,DRL,LDR,LRD,RDL,RLD。一般在遍历时遵循先左后有的原则,因此常用的遍历方法有三种:DLR。称为先序(根)遍历,LDR,称为中序(根)遍历。LRD,称为后序(根)遍历。
4.1 二叉树的遍历
如下图所示的一颗二叉树,该二叉树的先序遍历为ABFLDI,中序遍历为BLFAID,后序遍历为LFBIDA
5,二叉树与树,森林之间的转换
5.1 二叉树与树之间的转换
二叉树与树之间的转换实际上是将树转换成左孩子右兄弟二叉树。
5.2 二叉树与森林之间的转换
1,森林转换为二叉树
2,二叉树转换成森林
以上两个实质上都是左孩子右兄弟二叉树和 树或森林之间的转换
6,二叉树的创建
在前面的复习中,二叉树都是静态创建的,但是这实际开发中,二叉树往往是动态创建的。常用的动态创建二叉树的方法有中序先序法和#号法。
6.1 中序和先序创建二叉树
创建一颗二叉树的方法有如下两种:
- 中序遍历结果和先序遍历结果一起可以确定一颗二叉树
- 终须遍历结果和后序遍历结果一起可以确定一颗二叉树
注意:即使结合先序遍历和后序遍历的结果也无法确定一颗二叉树的结构。因为这两种遍历结果结合只能求解出根,不能确定左子树什么时候结束,右子树什么时候开始。
根据中序遍历和先序遍历的结果确定二叉树的基本思路如下:
在谈论基本思路先,先思考二叉树的中序遍历和先序遍历结果中根节点和左子树,右子树的特征:
在先序遍历中,先遍历根节点,然后遍历左子树,再遍历右子树
在中序遍历中,先遍历左子树,再遍历根结点,再遍历右子树。
所以如上描述的一样,先序遍历的特征是(根节点(左子树的根节点+左子树的子节点)(右子树的根结点+右子树的其他接待你))。中序遍历的特征是(左子树,根节点,右子树)
故一般思路为
- 通过先序遍历找到根节点,在通过根接单在中序遍历的位置找到左子树,右子树
- 根据左子树在先序遍历结果的顺序,找到左子树的根节点,视左子树为一颗独立的树,转第一个步骤
- 根据右子树在先序遍历结果的孙旭,找到右子树的根节点,视右子树为一颗独立的树,转第一个步骤
6.2 #号法创建树
单独使用先序遍历结果无法唯一确定一颗二叉树,但如果用#号法,先序遍历结果就可以唯一确定一颗二叉树。
#号法是让每一颗树都变成度数为2的树,度不为2的节点就用#符号补全。
看个例子:如DFE###B##
7 线索二叉树
7.1 什么是线索二叉树
把执行前驱和后继的指针称为线索,带有线索的二叉链表称为线索链表,带有线索的二叉树称为线索二叉树。
线索二叉树的结点结构定义
typedef struct BitNode
{
DataType data;
struct BitNode *lchild,*rchild;
int LTag;
int RTag;
}BitNode,*Bithrtree;
typedef struct BitNode *BiTree;
7.2 二叉树的线索化
将二叉树变为线索二叉树的过程称为线索化。按某种次序将二叉树线索化的实质是:按该次序遍历二叉树,在遍历的过程中用线索取代空指针。按照遍历方式,线索化也可分为先序线索化,中序线索化和后序线索化。其中先序线索化瘀后序线索化要比中序线索化稍难
8 赫夫曼树
8.1 什么是赫夫曼树
在了解赫夫曼树之前,先了解几个术语:
- 路径:它是指从某一节点到另一个节点的线路
- 树的路径长度:是从树根到树中每一个结点的路径长度之和。
- 树的带权路径:节点到树根之间的路径长度与该结点上权值的乘积之和
赫夫曼树是以一种树的带权路径最短的二叉树
8.2 赫夫曼树的构造
8.3 赫夫曼编码
上一篇: 实验三 静态链表实现学生成绩处理