哈夫曼算法和它的严格证明

哈夫曼算法

    • 最优哈夫曼树是啥
    • 算法步骤简介
    • 复杂度
    • 算法正确性证明

最优哈夫曼树是啥

有篇文章(字符串),想把它加密成01串。所以要给每个字符映射一个01串代表它,而且一个字符的01串不能是另一个的前缀,否则将出现二义性。所以可以把一颗二叉树的叶子节点看成字符,向左走和向右走分别为0和1,这样构造映射到的01串就不会有二义性,这个树就是哈夫曼树。为了使得01串总长度最小,就要构造最优哈夫曼树。显然每个字符的01串长度是字符节点的深度(到根节点经过的变数),所以使得 l e n = ∑ c n t i ∗ d e e p i , i ∈ σ len=\sum{cnt_i*deep_i},i\in\sigma len=cntideepi,iσ
最小。
其中 c n t i , d e e p i , σ cnt_i,deep_i,\sigma cnti,deepi,σ分别表示字符i出现的次数,字符i的叶子结点深度,字符集合。以下n是字符集大小。

算法步骤简介

采用贪心算法。一开始节点集合有n个字符节点,每个节点权为字符权重。每次选择剩下的节点中选两个权重最小的,合并成一个新节点,权重为两节点之和。删除两个节点,移入新节点。旧的两个节点就是新节点的左右儿子。知道集合里只有一个节点。

复杂度

每次集合减少一个点,用优先队列模拟选点过程的话,时间为 T = ∑ i = 2 n l o g 2 i + l o g 2 ( i − 1 ) = O ( n l o g n ) T=\sum_{i=2}^{n}log_2i+log_2(i-1)=O(nlogn) T=i=2nlog2i+log2(i1)=O(nlogn)

算法正确性证明

众所周知,贪心算法要满足最优子结构和第一步正确性。

  • 所以我就从这两方面下手:

    1.第一步正确性证明:
    令n个结点中最小的两个是x,y。就是证明们对于n个叶子节点的哈夫曼树,开始选x,y合并是可以构造可以出哈夫曼树的。即证明n个叶子节点的最优哈夫曼树集合中,一定有一棵,x,y处于层数最深的那层,且互为兄弟。

    • (1) 层数最深证明:
      现在有一棵按算法构造的树T,加密01串总长 度len。如果把层数比较浅的叶子z节点(按算法 c n t z > = c n t x cnt_z>=cnt_x cntz>=cntx)和 x交换,那么新的总长度 l e n ′ = l e n + ( d e e p z − d e e p x ) ∗ c n t z − ( d e e p z − d e e p x ) ∗ c n t x = l e n + ( d e e p z − d e e p x ) ∗ ( c n t z − c n t x ) ≥ l e n len'=len+(deep_z-deep_x)*cnt_z-(deep_z-deep_x)*cnt_x\\ =len+(deep_z-deep_x)*(cnt_z-cnt_x)\\ \ge len len=len+(deepzdeepx)cntz(deepzdeepx)cntx=len+(deepzdeepx)(cntzcntx)len
      所以交换深度一定不会让总长度变小。所以x,y一定层数最深的这棵树一定是最优的。

    • (2) x,y是兄弟证明:同层交换不改变总长度。所以某棵树xy不在一起的话,根据层数最深规则xy一定在同一层。所以设y现在的兄弟是z,把x和z换一下最优性不变而使得xy互为兄弟。所以一定有一棵最优树x,y互为兄弟。

    • 到这里第一步正确性就成立了。

  1. 最优子结构:
    这个比较好办。现在是n个点,弄完第一步后剩n-1个点,要证明这n-1个点也得构成最优树才能保证n个点也是最优树。证明:
    设n-1个点构成了T‘树,总长度为len’。此时n个点的树的 l e n = l e n ‘ + c n t x + c n t y len=len‘+cnt_x+cnt_y len=len+cntx+cnty显然len’最优才能保证len最优。
  • 所以满足最优子结构和第一步正确性,算法是合理的。

你可能感兴趣的:(证明,哈夫曼,算法)