哈夫曼树及其应用

1.哈夫曼树简介

        哈夫曼树,又称最优二叉树,如图中第三棵树,是带权路径长度(WPL)最短的树,可用来构造最优编码,用于信息传输数据压缩等方面,是一种应用广泛的二叉树。

2.相关概念

路径:树中一个节点到另一个节点之间的分支序列构成两个节点间的路径。

路径长度:路径上分支的条数

树的路径长度:从树根到每个节点的路径长度之和。

节点的权:该节点的数值。

带权路径长度:节点到树根间的路径长度与该点路径长度的乘积。

3.哈夫曼树的建立算法简述

1.根据给定的n个权值集合,先选出其中最小的两个权值构造新树,新二叉树的根节点为新增加的节点,其权值为两个最小树的权值之和。

2.删除已经选取的最小两颗子树,将新树加入到权值集合之中。

3.重复步骤一,步骤二即可

4.哈夫曼算法的实现

4.1.存储结构

        哈夫曼树一般采用静态三叉链表来存储。哈夫曼树里面没有度为1的结点,这类二叉树称为正则二叉树。对于n个叶子的二叉树,算法中构建了n-1个度为2的结点,所以哈夫曼树共有2n-1个节点,可以存储在一个大小为2n-1的一维数组中。

其中,weight为结点的权值,parent为结点的双亲结点,Lchild,Rchild分别为左孩子,右孩子。

代码如下:

#define N 30
#define M 2*N-1
typedef struct 
{
    int weight;
    int Parent,Lchild,Rchild;
}HTNode,Huffmantree[M+1];//0号单元不使用

4.2.哈夫曼树的算法代码实现:

void CrtHuffmanTree(HuffmanTree ht,int w[],int n)
{
    m=2*n-1;
    for(i=1;i<=n;i++)
        ht[i]={w[i],0,0,0};//初始化前n个元素称为根结点
    for(i=n+1;i<=m;i++)
        ht[i]={0,0,0,0};//初始化后n+1各元素为0;
    for(i=n+1;i<=m;i++)
        {
         select(ht,i-1,&s1,&s2);//选取权值最小的两个结点构造新结点
         ht[i].Weight=ht[s1].Weight+ht[s2].weight;//给新结点赋权值
         ht[i].Lchild=s1;ht[i].Rchild=s2;//赋新结点左右孩子指针
         ht[s1].Parent=i;ht[i].Parent=i;//改s1,s2的双亲指针
        }
}

这样就完成了哈夫曼树的建立。

5.哈夫曼树的编译码原理

5.1.前缀编码

        等长编码不能使信息得到有效的压缩,因此要设计压缩效率更高的编码,即不等长的编码。而不等长的编码要使各编码之间无需加分界符即可识别,其编码必须是前缀编码。 同一字符集中任何一个字符都不是另一个字符编码的前缀(最左子串),这种编码称为前缀编码。

5.2.哈夫曼编码过程

哈夫曼编码:

由于每个字符的哈夫曼编码是从根结点到相应叶子的路径上分支符号组成的串,字符不同,相应的叶子就不同,而从根到每个叶子的路径均是不同的,两条路径前半部分可能相同,但最后的恶路径一定经过分叉,所以一条路径不可能是另一条的前缀。所以哈夫曼编码是前缀码。

6.哈夫曼编码的算法实现

  • 从叶子结点开始,沿着双亲链追溯到根结点,每上升一层,则经过一条分支,便可得到一位哈夫曼编码值,左0(右1)。
  • 由于从叶子追溯到根结点的过程所得到的的编码串为逆串,因此,使用一个临时数组,每位编码从后向前存入数组中,由start控制存储的次序。
  • 到达根结点时,一个叶子的编码已经完成,此时将cd数组以start开始的串复制到动态申请的编码串空间即可。 

void crtHuffmanCOde(HuffmanTree ht,HuffmanCode hc,int n)
{
 char *cd;
 int start;
 cd=(char*)malloc(n*sizeof(char));
 cd[n-1]='\0';
 for(i=1;i<=n;i++)
    {
     start=n-1;c=i;p=ht[i].parent;
     while(p!=0)
        {--start;
         if(ht[p].Lchild==c)
             cd[start]='0';
         else
             cd[start]='1';
         c=p;p=ht[p].parent;
        }
      hc[i]=(char*)malloc((n-start)*sizeof(char));
      strcpy(hc[i],&cd[start];
    }
     free(cd);
}

 总结:

        哈夫曼编码是一种压缩数据的算法,它通过将出现频率较高的字符用较短的编码表示,而将出现频率较低的字符用较长的编码表示,从而达到压缩数据的目的。哈夫曼编码常用于数字信号处理、通信系统、数据传输和存储等领域,可以大幅减小数据存储和传输的成本,并提高数据传输的效率。同时,哈夫曼编码也可以用于加密和解密,在保护信息安全方面发挥重要作用。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值