vlambda博客
学习文章列表

平衡二叉树 & 红黑树 & 哈夫曼

~AVL:高度平衡二叉树

特点是:AVL树中任何节点的两个子树的高度最大差别为1。左Yes,右No


~红黑树 Red-Black Tree

R-B(Red-BlackTree)或红黑树是一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。其特性:

(1)每个节点或者是黑色,或者是红色。

(2)根节点是黑色。

(3)每个叶子节点(NIL)是黑色。⚠️叶子节点是指为空(NIL或NULL)的叶子节点

(4)如果一个节点是红色的,则它的子节点必须是黑色的。

(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

⚠️注意⚠️

(1)特性(3)中的叶子节点,是只为空(NIL或null)的节点。

(2)特性(5)确保没有一条路径会比其他路径长出俩倍。因而红黑树是相对是接近平衡的二叉树。

~应用:红黑树的应用比较广泛,主要是用它来存储有序的数据,时间复杂度是O(lgn),效率非常之高。例如,Java集合中的TreeMap和HashMap,都是通过红黑树去实现的。


~哈夫曼 /霍夫曼树 Huffman Tree

哈夫曼树 or 霍夫曼树是最优二叉树。

定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。 其中几个重要的概念:

(1) 路径和路径长度

定义:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。

例子:100和80的路径长度是1,50和30的路径长度是2,20和10的路径长度是3。

(2) 结点的权及带权路径长度

定义:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。

例子:节点20的路径长度是3,它的带权路径长度= 路径长度x权 = 3 x 20 = 60。

(3) 树的带权路径长度

定义:树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。

例子:示例中,树的WPL= 1x100 + 2x50 + 3x20 + 3x10 = 100 + 100 + 60 + 30 = 290。


~哈夫曼树构造

假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 

n个权值分别设为 w1、w2、…、wn,哈夫曼树的构造规则为:

1. 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);

2. 在森林中选出根结点的权值最小的两棵树进行合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;

3. 从森林中删除选取的两棵树,并将新树加入森林;

4. 重复(02)、(03)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

例子:以{5,6,7,8,15}为例,来构造一棵哈夫曼树。构造步骤如下:

  1. 创建森林,森林包括5棵树,这5棵树的权值分别是5,6,7,8,15。

  2. 在森林中,选择根节点权值最小的两棵树(5和6)来进行合并,将它们作为一颗新树的左右孩子(谁左谁右无关紧要,这里,我们选择较小的作为左孩子),并且新树的权值是左右孩子的权值之和。即,新树的权值是11。 然后,将"树5"和"树6"从森林中删除,并将新的树(树11)添加到森林中。

  3. 在森林中,选择根节点权值最小的两棵树(7和8)来进行合并。得到的新树的权值是15。 然后,将"树7"和"树8"从森林中删除,并将新的树(树15)添加到森林中。

  4. 在森林中,选择根节点权值最小的两棵树(11和15)来进行合并。得到的新树的权值是26。 然后,将"树11"和"树15"从森林中删除,并将新的树(树26)添加到森林中。

  5. 在森林中,选择根节点权值最小的两棵树(15和26)来进行合并。得到的新树的权值是41。 然后,将"树15"和"树26"从森林中删除,并将新的树(树41)添加到森林中。