树的定义和基本概念
定义:有线性结构
结点、结点的度、叶子、孩子、双亲、兄弟、树的度、结点的层次、深度、森林
二叉树
定义:与树没有直接联系。
特点:树中每一个结点的度小于等于2
满二叉树与完全二叉树:
满二叉树是完全二叉树的特殊情况,满二叉树中的每个结点的度都为2,完全二叉树中叶子结点出现在最后一层或者倒数第二层。
性质:
1、在二叉树的第i层至多有2^(i-1)个结点(等比数列
2、深度为k的二叉树至多有2^k-1个结点 (等差数列前n项和)
3、对任何一棵二叉树T,n0=n2+1 (度为0的结点个数
4、具有n个结点的完全二叉树的深度为 log 2n +1(向下取整)
5、按层次遍历编号,对一颗完全二叉树而言,如果i=1就是根结点,如果2i>n 那么i就是叶子结点 否则2i是它的左孩子。同理2i+1一样。如果2i+1>n,那么i没有右孩子,否则右孩子为2i+1
二叉树的存储结构
顺序存储
思路:从根结点起依次编号,分别存入创建的数组即可
缺点:浪费空间并且插入和删除结点的时候不方便。
链式存储
二叉链表
三元组:左孩子、右孩子、结点值
推广到三叉链表:增加了一个指向双亲的链域
线索链表
引出:用二叉链表存储的会有很多空的链域,用这些空的链域存储其他信息
线索二叉树:用二叉链表存储结点时候无法直接得到某一个结点的前驱与后继信息,这些信息是在动态搜索过程中得到的
增加了两个数域:LTag:0表示lchild域指示结点的左孩子 1表示lchild域指示结点的前驱 同理RLag:0表示rchild域指示结点的右孩子 1表示rchild域指示结点的后继。
备注:二叉树的线性化:由于线索化的实质是将二叉链表中的空指针改为指向前驱或者后继的线索,而前驱或者后继的信息只有在遍历过程中得到,因此线索化的过程即为在遍历过程中修改空指针的过程。
遍历二叉树
先序遍历:data\lchild\rchild
中序遍历:lchild\data\rchild
后序遍历:lchild\rchild\data
层次遍历:根据结点编号逐层遍历
树和森林
树的存储结构
双亲表示法:用一组连续空间存储树的结点,且加一个父结点在顺序表中的位置的数域
方便查找父结点所在位置
但是找孩子结点较麻烦,需要扫描数组
孩子表示法:把每个结点的孩子结点排列起来看成一个线性表,且以单链表做存储结构,则n个结点有n个孩子链表(叶子结点的孩子链表为空表)。而n个头指针又组成一个线性表,为了便于查找,采用顺序存储
带双亲的孩子链表
孩子兄弟表示法
树与二叉树的转化:树到二叉树:兄弟之间加线、除左孩子以外抹掉父结点与其他孩子之间的线、以树的根结点为轴心将树顺时针旋转45度
二叉树与树的转化:
森林转化成二叉树
二叉树转化成森林
树和森林的遍历:两种次序:先根遍历和后根遍历
赫夫曼树及其应用
最优二叉树(赫夫曼树)
概念:路径长度、树的路径长度、结点的带权路径长度、树的带权路径长度
构造赫夫曼树:
赫夫曼编码:
赫夫曼树、赫夫曼编码域、前缀编码的关系:通过构造赫夫曼树可以得到赫夫曼编码,前缀编码的实现途径之一是构造赫夫曼树。