你只管努力,其他的交给天意
树是一种非线性的数据结构,如果一组数组节点之间存在复杂的一对多关联时,程序可以考虑使用树来存储这组数据。Treemap本身就是一颗红黑树,红黑树又是一种特殊的排序二叉树。
树:指的是N个有父子关系的节点的有限集合
对于这个集合,它满足如下条件:
为了实现这种数据结构,程序必须记录节点与非节点的父子关系,有俩种选择:父节点表示法、子节点表示法
定义树节点时增加一个Parent域,该域用于保存该节点的父节点在数组中的位置索引,通过这种方式记录书中节点之间的父子关系,添加新节点时将新节点的parent域的值设为其父节点在数组中的索引。
每个节点都可以快速找到它的父节点,但如果要找某个节点的所有子节点就比较麻烦,程序要遍历整个节点数组。
让父节点记住它的所有子节点
二叉树指的是每个节点最多只能有俩个子树的有序树,左边的子树称为左子树,右边的子树称为右子树
树个二叉树的俩个重要区别:
当i=1时,节点i是二叉树的根;若i>1,则节点的父节点是i/。
若
,则节点i有左孩子,左孩子的编号是2i,否则,节点无左孩子,并且是叶子节点。
若
,则节点i有右孩子,有孩子的编号是
;否则节点无右孩子。
实现二叉树这种数据结构,右三种选择:
二叉树每层的节点数最多为,这个二叉树最多能包含节点为
,因此只要定义一个
的数组即可储存这棵树。二叉树采用顺序存储可能会造成一定的空间浪费。
对于二叉链表的二叉树,因为程序采用链表来记录树中所有节点,所以添加节点没有限制,也不会像顺序存储那样产生大量的空间浪费。这种二叉链表的存储方式在遍历树节点时效率不高,指定节点访问父类节点也比较困难,程序必须采用遍历二叉树的方式搜索其父节点。
为了克服二叉链表存储方式中访问父类节点不方便的问题,可以将二叉链表扩展成三叉链表。三叉链表存储方式是二叉链表的一种改进,通过为树节点增加一个parent引用,可以让每个节点都能方便的访问父节点。
遍历二叉树指的是按照某种规律依次访问二叉树的每个节点,对二叉树的遍历过程就是将非线性结构的二叉树中的节点排列在一个线性序列上升的过程。如果采用顺序结构保存二叉树,程序遍历二叉树将非常容易,直接遍历底层数组即可,如果采用链表保存二叉树的节点,则有俩中遍历方式:
深度优先遍历:这种遍历将先访问到树中最深层析的节点。它右可分为3中(前序、中序、后序)
广度优先遍历:逐层访问每层的节点,先访问根节点,然后访问第二层节点,广度遍历法又被称为按层遍历
DLR(L:左子树、D:根、R:右子树)
LDR
LRD
先遍历二叉树的第一层,再遍历根节点的俩个子节点,逐层遍历二叉树所有节点。
为了实现广度优先遍历,可以借助FIFO特征队列来实现:
三者之间一一映射,可以相互转换
多叉树向二叉树转换:
二叉树向多叉树、森林恢复:
因为多叉树和二叉树可以自由转换,因此,普通树可以以二叉树的形式保存,实际需要的时候,再将二叉树转换为普通树
通常使用三叉链表来保存二叉树
哈夫曼树又被称为最优二叉树,是一类带权路径最短的二叉树,在信息检索时常用。
节点之间的路径长度:从一个节点到另一个节点之间的分支数量称为俩个节点之间的路径长度
树的路径长度:从根节点到树中每一个节点的路径长度之和
节点的带权路径长度:从该节点到根节点之间的路径长度与节点上权的乘机
树的带权路径长度:树中所有叶子节点的带权路径长度之和
带权路径最小的二叉树被称为哈夫曼树或最有二叉树。
对于具有n个叶子节点的哈夫曼树,一共需要个节点。
【对于二叉树来说,有三种类型节点:度数为0、1、2。而哈夫曼树的非叶子节点都是由俩个节点合并产生】
从哈夫曼根节点开始,对左子树分配代码“0”,对右子树分配代码“1”,一直到达叶子节点,然后,将从树根沿每条路径到达子节点的代码排列起来,便得到了每个叶子节点的哈夫曼编码。
采用哈夫曼树原理构造的二进制编码,使电文总最短。
哈夫曼编码有一条规矩:假设有N个叶子节点需要编码,最终得到的哈夫曼一定有N层,哈夫曼编码得到的二进制码的最大长度为N-1.
排序二叉树是一种特殊结构的二叉树,通过它可以非常方便地对树中所有节点进行排序和索引。排序二叉树要么是空树,要么有以下性质:
创建排序二叉树的步骤:
当程序从排序二叉树中删除一个检点后,为了保持为排序二叉树,必须对该排序二叉树进行维护。
被删除的节点是叶子节点,则只需将它从父节点中删除
被删除节点p只有左子树,将p的左子树pL添加成p的父节点的左子树即可;被删除节点p只有右子树,将p的右子树pR添加成p的父节点的右子树即可
若被删除节点p的左右树均为空:
将pL设为p的父节点q的左或右子节点(取决于p是其父节点q的左右子节点),将pR设为p节点的中序前趋节点s的右子节点(s是pL最右下的节点,也就是pL子树中最大的节点)
以p节点的中序前趋或后继替代p所指节点,然后再从原排序二叉树中删除中序前趋或后继节点
排序二叉树虽然可以快速检索,但如果插入的节点本身就是有序的,那么最后排序二叉树将变成链表:只有左节点或右节点。这时排序二叉树就是普通链表,检索效率就会很差。
红黑树的提出为了改善排序二叉树的不足。
红黑树并不是真正的平衡二叉树,实际应用中,红黑树的统计性能要高于平衡二叉树,但极端性能略差
红黑树在原有二叉树上增加如下几个要求: