二叉树的应用
1 二叉排序树(BST)
l 特点:
左子树结点值 < 根结点值 < 右子树结点值
l 查找
算法思想:若二叉排序树为非空,则给定值与根结点的关键字比较,若相等,则查找成功;若不等,则当根结点的关键字大于给定的关键字值时,在根结点的左子树查找,否则根结点的右子树查找。(有递归和非递归算法实现)
l 插入
【注】二叉树是动态集合,树的结构通常不是一次性形成的,而是在查找过程中,当树中不存在关键字等于给定值得结点时再插入。
算法思想: 若原二叉排序树(或递归子树)为空,则直接插入结点; 否则若关键字k小于根结点关键字,则插入到根结点的左子树,反之,插入到根结点右子树。
二叉排序树插入新结点一定是某个叶结点。
l 构造
算法思想: 依次输入数据元素,并调用插入函数完成插入动作
l 删除
【引】删除动作要保证二叉排序树的性质不会丢失。
1. 叶结点,直接删除
2. 该结点z只有一棵左子树或右子树,则让z的子树成为z父节点的子树。
3. 该结点z有左右两棵子树,则令z的直接前驱(或直接后继)替代z(值替换),然后从二叉排序树中删除这个直接前驱(或直接后继)。这样就转换成了第一种或者第二种情况。(值替换->1,2类型删除)
l 查找效率分析
平均查找长度(ASL)
例:左上图ASL=(1x1+2x2+3x4+4x2+5x1)/10= 3
【注】
1 相同关键字可组成的不同二叉排序树(即输入关键字的顺序不同)。
2 因此,二叉排序树查找算法的平均查找长度,主要取决于树的高度,即与二叉树的排序树的形态有关。
3 二叉平衡树(左右子树高度差的绝对值不超过1),它的平均查找长度为O(log2n)
平衡二叉树(AVL)
【引】为了避免树的高度增长过快,降低二叉排序树的性能。 规定在插入和删除二叉树结点时,要保证任意结点的左,右子树的高度差绝对值不超过1,这样的树称之为二叉平衡树。
平衡因子:结点左子树和右子树的高度差,可能取值 -1,0, 1
平衡二叉树保证平衡的思想:
每当在二叉排序树中插入(或删除)一个结点时,首先要检查其插入(或删除)路径上的结点是否因为此次操作而导致了不平衡。如果导致了不平衡,则先找到离插入结点最近的平衡因子绝对值大于1的结点A,再对以A为根的子树,在保持二叉排序树特性的前提下,调整各结点的位置关系,使之重新达到平衡。
【注】 每次调整的对象都是最小不平衡子树,即在插入(或删除)路径上里离插入(或删除)结点最近的平衡因子的绝对值大于1的结点作为根的子树。
平衡二叉树插入过程前半部分与二叉排序树相同,如果插入造成失衡,一般有以下四种。
1. LL平衡旋转(右单旋转)
【说明】是由于在结点A的左孩子(L)的左子树(L)上插入了新结点,A的平衡因子由1增加到2,导致以A为根的子树失去平衡,需要一次向右的旋转操作。
平衡操作:将A的左孩子B向右上旋替代A成为根结点,将A结点向右下旋转成为B 的右子树的根结点,而B的原右子树的则作为A结点的左子树。
2. RR平衡旋转(左单旋转):同1反向,就是失衡结点A的右孩子B左上旋,A左下旋,B的左子树成为失衡结点A的右子树。
3 RL平衡旋转(先左后右双旋转)。
【说明】:由于在A的右孩子(R)的左子树(L)上插入了新结点,A的平衡因子有-1减至-2,导致以A为根的子树失去平衡,需要进行两次旋转操作。先右旋转后左旋转。
即:先将A结点的右孩子B的左子树的根结点C向右上旋转提升到B结点的位置,然后再把C结点向左上旋转到A结点的位置。同时注意B的左子树的根结点C如果有左右子树,则分别作为A的左子树和B的右子树。
4,LR平衡旋转(先左后右双旋转)
失衡原理:A结点的左孩子(L)的右子树(R)上插入新结点,导致A的平衡因子由1增至2而失衡。
平衡原理:将A结点的左孩子B的右子树的根结点C先向左上旋到B处,再右上旋到A处。同时注意c左右子树的变化。
【注】RL和LR旋转式,究竟新结点插入在C的左子树还是右子树上,都不影响旋转过程。上例都以插入C的左子树为例。
平衡二叉树的查找
在平衡二叉树上查找过程和二叉排序树相同,因此在查找过程中和给定值进行比较的关键字比较的个数不超过树的深度。【可是二叉排序树的形态和输入序列的顺序有关,即树的深度不同。】
可以证明,还有n个结点的平衡二叉树的最大深度为O(log2N),因此平衡二叉树的平均查找长度为O(log2N)
[证明]:
平衡二叉树在高度为h情况下 最小节点数为Fibonacci数列(下标并不恰好对应),最多节点数则为2^h。 所以在节点数为n的情况下其最大高度应该为对应刚好比他大fibonacci数列所对应的高度(反证法)
哈夫曼树
1. 【引】
实际应用中,树中结点常常被赋予某种特殊意义的数值,称为该结点的权。
于是,从树根结点到任意结点的路径长度(即经过的边数)与该结点上权值的乘积称为该结点的带权路径长度。树的所有叶结点的带权路径长度之和称之为该树的带权路径长度。记为
WPL
其中,Wi是第i个叶结点的权值,Li是该叶结点到根结点的路径长度。
在含有N个带权叶子结点的二叉树中,其中带权路径长度(WPL)最小的二叉树称为哈夫曼树,也称最优二叉树。
2. 哈夫曼树的构造
前提:给定N个权值分别为w1,w2…….wN的结点。
算法描述:
A. 将这N个结点分别作为N棵仅含一个结点的二叉树,构成森林F
B. 构造一个新结点,并从F中选取两棵根结点权值最小的树作为新结点的左右子树,并且将新结点的权值置为左右子树上根结点的权值之和。
C. 从F中删除刚才选取的两棵树,同时将新得到的树加入F中。
D. 重复2),3),直至F中只剩下一棵树为止。
【特点】
i. 每个初始结点最终都成为叶结点,并且权值最小的结点到根结点的路径长度越大。
ii. 构造过程中共新建了N-1个结点(双分支节点 N2=N0-1),因此哈夫曼树中结点总数为2N-1.
iii. 每次构造都选择2棵树作为新结点的孩子,因此哈夫曼树中不存在度为1的结点。
1. 哈弗曼编码
【引】
固定长度编码:每个字符用同样长度的二进制位来表示。反之,用不同长度称之为可变长度编码。 这样一来,高频率字符赋以短编码,低频率赋以长编码,从而使平均字符编码长度减短,起到压缩数据效果,哈夫曼编码就是这种可变长度编码。
前缀编码:没有一个编码是另一个编码的前缀。如 0,101,100
哈夫曼树à哈夫曼编码
将每个出现的字符当作一个独立的结点,其权值为它出现的频度(或次数),构造出对应的哈夫曼树。