利用最小堆求霍夫曼编码字长

算法原理

霍夫曼编码字长就是其对应二叉树叶子节点的路径长度。显然根节点的长度为0,子节点的编码长度比父母节点的长度大1。因此建立霍夫曼树的过程中保存指向父母节点的地址即可,然后从叶子节点往上搜寻,每次长度加1,直到根节点为止。实现的方法分为如下几步:

初始化最小堆

实现过程中开辟2倍空间的节点,实际排序建立二叉树只用一半,后面一半保存叶子节点的所指的父母节点。
代码如下:

leaf_name=['A','B','C','D','E','F','G','H','A','B','C','D','E','F','G','H'];
leaf_data=[10,1,1,11,1,1,8,5,0,0,0,0,0,0,0,0];
leaf_addr=[9,10,11,12,13,14,15,16,0,0,0,0,0,0,0,0];
my_heap=heap();
my_heap.min_heap_create(leaf_name,leaf_data,leaf_addr);
my_heap.heap_set_size(8) ;
my_heap.min_heap_adjust();
my_heap.heap_set_size(16) ;
my_heap.min_heap_print();
my_heap.heap_set_size(8) ;

运行结果如下:
node 01–>addr 10–>name B–>data 1
node 02–>addr 13–>name E–>data 1
node 03–>addr 11–>name C–>data 1
node 04–>addr 16–>name H–>data 5
node 05–>addr 09–>name A–>data 10
node 06–>addr 14–>name F–>data 1
node 07–>addr 15–>name G–>data 8
node 08–>addr 12–>name D–>data 11
node 09–>addr 00–>name A–>data 0
node 10–>addr 00–>name B–>data 0
node 11–>addr 00–>name C–>data 0
node 12–>addr 00–>name D–>data 0
node 13–>addr 00–>name E–>data 0
node 14–>addr 00–>name F–>data 0
node 15–>addr 00–>name G–>data 0
node 16–>addr 00–>name H–>data 0

依次从堆里取最小的两个节点构建二叉树

构建过程中保存子节点指向父母节点的地址,保存在data字段,同时父母节点的data字段为二者之和,addr字段为当前堆长度加一个单位。循环直到堆只有一个元素位置。代码如下:

while(my_heap.size >1)
    my_heap.min_heap_popup();
    temp_data1=my_heap.data(my_heap.size+1);
    temp_addr1=my_heap.addr(my_heap.size+1);

    my_heap.min_heap_popup();
    temp_data2=my_heap.data(my_heap.size+1);
    temp_addr2=my_heap.addr(my_heap.size+1);
    
    my_heap.data(temp_addr1)=my_heap.size+1;
    my_heap.data(temp_addr2)=my_heap.size+1;

    my_heap.min_heap_insert('X',(temp_data1+temp_data2),my_heap.size+1);
    temp_size =my_heap.size;
    my_heap.heap_set_size(16) ;%方便查看打印有意将堆长度设置到最大值
    my_heap.min_heap_print();
    my_heap.heap_set_size(temp_size) ;%设置成实际
end

依次循环的显示结果如下:


node 01–>addr 11–>name C–>data 1
node 02–>addr 16–>name H–>data 5
node 03–>addr 14–>name F–>data 1
node 04–>addr 12–>name D–>data 11
node 05–>addr 09–>name A–>data 10
node 06–>addr 15–>name G–>data 8
node 07–>addr 07–>name X–>data 2
node 08–>addr 10–>name B–>data 1
node 09–>addr 00–>name A–>data 0
node 10–>addr 00–>name B–>data 7
node 11–>addr 00–>name C–>data 0
node 12–>addr 00–>name D–>data 0
node 13–>addr 00–>name E–>data 7
node 14–>addr 00–>name F–>data 0
node 15–>addr 00–>name G–>data 0
node 16–>addr 00–>name H–>data 0


node 01–>addr 07–>name X–>data 2
node 02–>addr 16–>name H–>data 5
node 03–>addr 06–>name X–>data 2
node 04–>addr 12–>name D–>data 11
node 05–>addr 09–>name A–>data 10
node 06–>addr 15–>name G–>data 8
node 07–>addr 11–>name C–>data 1
node 08–>addr 10–>name B–>data 1
node 09–>addr 00–>name A–>data 0
node 10–>addr 00–>name B–>data 7
node 11–>addr 00–>name C–>data 6
node 12–>addr 00–>name D–>data 0
node 13–>addr 00–>name E–>data 7
node 14–>addr 00–>name F–>data 6
node 15–>addr 00–>name G–>data 0
node 16–>addr 00–>name H–>data 0


node 01–>addr 05–>name X–>data 4
node 02–>addr 16–>name H–>data 5
node 03–>addr 15–>name G–>data 8
node 04–>addr 12–>name D–>data 11
node 05–>addr 09–>name A–>data 10
node 06–>addr 07–>name X–>data 5
node 07–>addr 11–>name C–>data 5
node 08–>addr 10–>name B–>data 1
node 09–>addr 00–>name A–>data 0
node 10–>addr 00–>name B–>data 7
node 11–>addr 00–>name C–>data 6
node 12–>addr 00–>name D–>data 0
node 13–>addr 00–>name E–>data 7
node 14–>addr 00–>name F–>data 6
node 15–>addr 00–>name G–>data 0
node 16–>addr 00–>name H–>data 0


node 01–>addr 15–>name G–>data 8
node 02–>addr 04–>name X–>data 9
node 03–>addr 12–>name D–>data 11
node 04–>addr 09–>name A–>data 10
node 05–>addr 05–>name X–>data 4
node 06–>addr 07–>name X–>data 5
node 07–>addr 11–>name C–>data 5
node 08–>addr 10–>name B–>data 1
node 09–>addr 00–>name A–>data 0
node 10–>addr 00–>name B–>data 7
node 11–>addr 00–>name C–>data 6
node 12–>addr 00–>name D–>data 0
node 13–>addr 00–>name E–>data 7
node 14–>addr 00–>name F–>data 6
node 15–>addr 00–>name G–>data 0
node 16–>addr 00–>name H–>data 4


node 01–>addr 09–>name A–>data 10
node 02–>addr 12–>name D–>data 11
node 03–>addr 03–>name X–>data 17
node 04–>addr 15–>name G–>data 3
node 05–>addr 05–>name X–>data 4
node 06–>addr 07–>name X–>data 5
node 07–>addr 11–>name C–>data 5
node 08–>addr 10–>name B–>data 1
node 09–>addr 00–>name A–>data 0
node 10–>addr 00–>name B–>data 7
node 11–>addr 00–>name C–>data 6
node 12–>addr 00–>name D–>data 0
node 13–>addr 00–>name E–>data 7
node 14–>addr 00–>name F–>data 6
node 15–>addr 00–>name G–>data 3
node 16–>addr 00–>name H–>data 4


node 01–>addr 03–>name X–>data 17
node 02–>addr 02–>name X–>data 21
node 03–>addr 09–>name A–>data 10
node 04–>addr 15–>name G–>data 3
node 05–>addr 05–>name X–>data 4
node 06–>addr 07–>name X–>data 5
node 07–>addr 11–>name C–>data 5
node 08–>addr 10–>name B–>data 1
node 09–>addr 00–>name A–>data 2
node 10–>addr 00–>name B–>data 7
node 11–>addr 00–>name C–>data 6
node 12–>addr 00–>name D–>data 2
node 13–>addr 00–>name E–>data 7
node 14–>addr 00–>name F–>data 6
node 15–>addr 00–>name G–>data 3
node 16–>addr 00–>name H–>data 4


node 01–>addr 01–>name X–>data 38
node 02–>addr 03–>name X–>data 1
node 03–>addr 09–>name A–>data 1
node 04–>addr 15–>name G–>data 3
node 05–>addr 05–>name X–>data 4
node 06–>addr 07–>name X–>data 5
node 07–>addr 11–>name C–>data 5
node 08–>addr 10–>name B–>data 1
node 09–>addr 00–>name A–>data 2
node 10–>addr 00–>name B–>data 7
node 11–>addr 00–>name C–>data 6
node 12–>addr 00–>name D–>data 2
node 13–>addr 00–>name E–>data 7
node 14–>addr 00–>name F–>data 6
node 15–>addr 00–>name G–>data 3
node 16–>addr 00–>name H–>data 4


node 01–>addr 01–>name X–>data 38
node 02–>addr 03–>name X–>data 1
node 03–>addr 09–>name A–>data 1
node 04–>addr 15–>name G–>data 3
node 05–>addr 05–>name X–>data 4
node 06–>addr 07–>name X–>data 5
node 07–>addr 11–>name C–>data 5
node 08–>addr 10–>name B–>data 1
node 09–>addr 00–>name A–>data 2
node 10–>addr 00–>name B–>data 7
node 11–>addr 00–>name C–>data 6
node 12–>addr 00–>name D–>data 2
node 13–>addr 00–>name E–>data 7
node 14–>addr 00–>name F–>data 6
node 15–>addr 00–>name G–>data 3
node 16–>addr 00–>name H–>data 4

对建立的二叉树进行结果分析

从最后一次显示结果来看,节点09~16的data字段保存了父节点的地址,利用代码求取各自的编码字长,然后保存在addr字段里面。执行my_heap.heap_len_encode(len+1)如下:

 function heap_len_encode(heap,n)
     for i=n:heap.size
         heap.addr(i)=1;
         while(heap.data(i) >1)
           heap.data(i)=heap.data(heap.data(i));
           heap.addr(i)=heap.addr(i) +1;
         end
     end                
 end

运行结果如下:


node 01–>addr 01–>name X–>data 38
node 02–>addr 03–>name X–>data 1
node 03–>addr 09–>name A–>data 1
node 04–>addr 15–>name G–>data 3
node 05–>addr 05–>name X–>data 4
node 06–>addr 07–>name X–>data 5
node 07–>addr 11–>name C–>data 5
node 08–>addr 10–>name B–>data 1
node 09–>addr 02–>name A–>data 1
node 10–>addr 05–>name B–>data 1
node 11–>addr 05–>name C–>data 1
node 12–>addr 02–>name D–>data 1
node 13–>addr 05–>name E–>data 1
node 14–>addr 05–>name F–>data 1
node 15–>addr 02–>name G–>data 1
node 16–>addr 03–>name H–>data 1

统计字符A~H的码长

字符ABCDEFGH
码长25525523
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值