赫夫曼(Huffman)树/编码

霍夫曼编码(Huffman Coding) 霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种。 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。 霍夫曼编码的具体步骤如下: 阅读详情

 

一 . 基本概念:

    赫夫曼树:给定带权的N个叶子构成的所有二叉树中,树的带权路径长度最小的二叉树(最优二叉树)

    带权路径长度:所有树叶到树根之间的路径长度与该节点上权的乘积

    权:赋予节点的有意义的参数

 

二 . 赫夫曼树的构造

    例:设权值集合{2,4,5,7}

    1.根据权值进行排序,取最小的两个叶子(2,4),较小的在左,较大的在右。添加一个新节点,节点的权值为它俩的权值和,构成一颗二叉树:

                                             

    2.用得到的节点作为新的叶子,重复第一步:

                                               

    3.一直重复构造,直到所有子叶都取完

                                            

    所以共需要进行n-1次构造,总共有 n+n-1 = 2n -1 个节点;

    可以证明,这样构造的二叉树是带权路径长度最小的二叉树

 

三 . 赫夫曼编码

    1.数据压缩(编码):把文件中的每个字符转换成一个唯一的二进制位串,且串里面不能包含其它字符的表示串。

    2.赫夫曼编码方法:如上例,设权为字符在文档中的重复次数,权值集合为{A:2,B:4,C:5,D:7},从根节点开始,向左是0,向右是1

                                                       

                那么

                         A的编码为:110。

                         B的编码为:111。

                         C的编码为:10。

                         D的编码为:0。

    3.代码实现:(C语言)

        头文件等:

#include <stdio.h>
#include <stdlib.h>
#define MAXINT 32767;

typedef struct
{
  char Character;
  unsigned int Weight;//权重
  unsigned int Parent, Lchild, Rchild;//双亲节点,左子节点,右子节点
}HTNode;

 

        a.生成霍夫曼树:

 

// n : 总叶子数  m: 用于构造Huffman树的数组大小(2n-1)
//k, j : 循环变量
//C, W : 接收字符和权时的中转变量
//Min_w1, Min_w2 : 用于存储两个最小权
//p1, p2 : 存储两个最小权数组的下标
void Great_Huffman(unsigned int n, HTNode HT[])
{
  int k , j;
  unsigned int W;
  char C;
  int m = 2*n - 1;
  //输入n个字符及其权
  for(k = 0; k < n; k++)
  {
    printf("input char and Weight : ");
    while((C = getchar()) == '\n');
    scanf("%d", &W);
    HT[k].Character = C;
    HT[k].Weight = W;
    HT[k].Parent = HT[k].Lchild = HT[k].Rchild = 0;//初始化
  }
  //初始化之后用于连接子叶的n-1个节点
  for(k = n; k < m; k++)
  {
    HT[k].Character = '\0';
    HT[k].Weight = 0;
    HT[k].Parent = HT[k].Lchild = HT[k].Rchild = 0;
  }
  //构造赫夫曼树
  int Min_w1, Min_w2;
  int p1, p2;
  //外层循环用于构造新的节点
  for(k = n; k < m; k++)
  {
    Min_w1 =  Min_w2 = MAXINT;//初始化最小值
    p1 = p2 = 0;//初始化下标
    //内层循环用于寻找构造新节点的两个最小权节点
    for(j = 0; j < k; j++)
    {
      if(HT[j].Parent == 0)//如果这个子叶尚未合并
      {
        if(HT[j].Weight < Min_w1)//更新最小权
        {
          Min_w2 = Min_w1;
          p2 = p1;
          Min_w1 = HT[j].Weight;
          p1 = j;
        }
        else if(HT[j].Weight < Min_w2)//更新次小权
        {
          Min_w2 = HT[j].Weight;
          p2 = j;
        }
      }
    }
    HT[p1].Parent = HT[p2].Parent = k;
    HT[k].Lchild = p1; HT[k].Rchild = p2;
    HT[k].Weight = HT[p1].Weight + HT[p2].Weight;
  }
}

    (注意输入格式,字符和权用空格隔开)

   :

    b.生成霍夫曼编码

//k : 循环变量
//sp : 编号指针,指向目前编号位,从后往前
//fp :双亲的下标
//p : 当前叶子下标
//HF : 暂时存储当前子叶的赫夫曼编码
void Huffman_Coding(unsigned int n, HTNode HT[])
{
  int k;
  int sp, fp;
  char *HF;//当前编码
  HF = (char *)malloc(n*sizeof(char));
  int p;
  for(k = 0; k < n; k++)
  {
    sp = n-1; p = k; fp = HT[k].Parent;
    //从叶子搜索直到根节点
    while(fp != 0)
    {
      if(HT[fp].Lchild == p)//如果当前节点是左子树
        HF[sp] = '0';
      else
        HF[sp] = '1';
      sp--;
      fp = HT[fp].Parent;
      p = fp;
    }
    //显示编码
    printf("\n%c : ", HT[k].Character);
    sp++;
    while(sp < n)
    {
      printf("%c",HF[sp]);
      sp++;
    }
  }
}

 

赫夫曼编码树(图解+完整代码) 赫夫曼树的构建与赫夫曼编码的图解剖析与完整代码,包含定长编码、变长编码、前缀码 阅读详情

相关推荐

二叉树的应用—Huffman编码与译码 哈夫曼树

实验五:二叉树的应用—Huffman编码与译码 实验目的:熟练掌握二叉树的基本操作操作,应用二叉树的结构解决实际问题,熟练掌握Huffman树和Huffman编码的构造方法。 实验内容:设计实现Huffman树的创建算法,并利用Huffman树进行编码和译码。 要求:1.在“Huffman编码“基础上的实现译码操作如输入“10010”译出相应的字符。 2.选做:(1)增加统计原文中各字符权值的功能,(2)将原文进行编码。 代码阅读:表达式树的创建与求值。 //算法5.11 根据赫夫曼树求赫夫曼

qq_54008392的博客 3084

霍夫曼编码详解

文章目录 霍夫曼编码 最佳变长编码 霍夫曼编码 霍夫曼编码的步骤 例 单符号离散无记忆信源 L-Z编码 总结 霍夫曼编码 最佳变长编码 最佳码: 对于某一信源和某一码符号集来说,若有一唯一可译码,其平均码长小于所有其他唯一可译码的平均长度。 紧致码 香农(Shannon) 费诺(Fano) 霍夫曼(Huffma ) 霍夫曼编码 在霍夫曼编码算法中, 固定长度的信源输出分组将映射成可变长度的二进制分组。该过程称为定长到变长编码。 其思想是将频繁出现的固定长度序列映射成较短的二进制序列, 而将出现频率较低的固

timerring的博客 1万+

某套通信系统含有8 种字符,每种字符出现概率分别为{2, 15, 30, 8, 10, 5, 12, 18},为其设计Huffman 编码。赫夫曼编码,C语言实现。

数据结构之赫夫曼编码 !!!注意!!! 创建文件时请以.cpp结尾,否则报错。 #include<stdio.h> #include<stdlib.h> #include<string.h> #define TRUE 1 /*状态码预定义*/ #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #def

m0_46560176的博客 7960

赫夫曼树 详细讲解

1、基本介绍 给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍夫曼树。 赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近。 2、赫夫曼树几个重要概念和举例说明 路径和路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1 结点的权及带权路径长

舒克日记的博客 4240

重温经典之赫夫曼(Huffman)编码

先看看赫夫曼树 假设有n个权值{w1,w2,…,wn},构造一个有n个叶子结点的二叉树,每个叶子结点权值为wi,则其中带权路径长度WPL最小的二叉树称作赫夫曼树或最优二叉树。   赫夫曼树的构造,赫夫曼最早给出了带有一般规律的算法,俗称赫夫曼算法。如下: (1)根据给定的n个权值{w1,w2,…,wn}构造n棵二叉树的集合F={T1,T2,…,Tn},其中Ti中只有一个权值为wi的根结点,

SuperFC之替天行道 5301

Huffman编码

Huffman编码 霍夫曼编码(英语:Huffman Coding),又译为哈夫曼编码、赫夫曼编码,是一种用于无损数据压缩的熵编码(权编码)算法。由美国计算机科学家大卫·霍夫曼(David Albert Huffman)在1952年发明。(来源于维基百科) 是一种变长的编码方式,对出现频率高的字符采用较短的编码,而对出现频率较低的字符采用较长的编码(在对字符进行变长编码时,注意要满足前缀码规则:...

qq_43271202的博客 2700

算法设计与分析——哈夫曼树/赫夫曼树(Huffman Tree)和哈夫曼编码/赫夫曼编码(Huffman Coding)

赫夫曼编码可以很有效地压缩数据:通常可以节省20%~90%的空间,具体压缩率依赖于数据的特性。我们将待压缩数据看做字符序列。根据每个字符的出现频率,赫夫曼贪心算法构造出字符的最优二进制表示。

冯·诺依曼 1万+

图文讲解Huffman树

本文通过图文介绍Huffman树的构成,重点在于理解Huffman树的形成原理,另外给出Huffman树的参考代码。之后通过文本压缩的例子来介绍Huffman编码,本文将从以下几个方面来介绍: 什么是Huffman树 案例介绍Huffman树的构成 Huffman编码 Huffman编码的应用 什么是Huffman树 Huffman树是一种树状的数据结构。任何一种数据结构都是用来解决特定的问题,那么首先我们先来弄出清楚Huffman树解决什么样的问题? 现在有一些不同数值的节点(图中蓝色),要把这些节

Black先森的博客 1505

数据结构Huffman树及赫夫曼(哈夫曼)编码的C语言实现

实验要求 1.输入一段100~200字的英文短文,存入一文件a中。 2.写函数统计短文出现的字母个数n及每个字母出现的次数。 3.写函数以字母出现的次数作权值,建Haffman树(n个叶子),给出每个字母的Huffman编码。 4.用每个字母编码对原短文进行编码,码文存入文件b中。 5.用Huffman树对b中码文进行译码,结果存入文件c中,比较a,c是否一致,以检验编码、译码的正确性。 程序分析...

学习记录 9253

第十二篇:Huffman树&&Huffman编码(附完整源码)

Huffman Tree简介     赫夫曼树(Huffman Tree),又称最优二叉树,是一类带权路径长度最短的树。假设有n个权值{w1,w2,...,wn},如果构造一棵有n个叶子节点的二叉树,而这n个叶子节点的权值是{w1,w2,...,wn},则所构造出的带权路径长度最小的二叉树就被称为赫夫曼树。     这里补充下树的带权路径长度的概念。树的带权路径长度指树中所有叶子节点到根节点的

u012426327的专栏 669

Huffman赫夫曼树

描述: 对输入的英文大写字母进行统计概率 然后构建哈夫曼树,输出是按照概率降序排序输出Huffman编码。 输入: 大写字母个数 n 第一个字母 第二个字母 第三个字母 ... 第n个字母 输出: 字母1 出现次数 Huffman编码 字母2 出现次数 Huffman编码 字母3 出现次数 Huffman编码 … 字母n 出现次数 Huffman

孟凡驰的博客 2351

赫夫曼树(Huffman树)及赫夫曼编码

了解赫夫曼树前需要了解以下概念: 路径:从树中某结点到另一结点之间的分支构成这两个结点间的路径。 路径长度:路径上的分支数。 结点的带权路径长度:从树根到该结点的路径长度与结点上权的乘积。 树的带权路径长度:树中所有叶子结点的带权路径长度之和 (WPL)。 例如: 赫夫曼树(Huffman树):又称最优二叉树,它是n个带权叶子结点构成的所有二叉树中,带权路径长度WPL最小的二叉树。 Huff...

欢迎来到我的世界 3628

算法——霍夫曼编码

霍夫曼编码(Huffman coding)是一种数据压缩算法,由David A. Huffman提出。它基于将频率较高的字符用较短的编码表示,而将频率较低的字符用较长的编码表示的原理,从而实现对数据的高效压缩。霍夫曼编码的核心思想是构建一棵霍夫曼树(Huffman tree)。首先,统计待压缩的数据中每个字符出现的频率。然后,根据频率来构建霍夫曼树,其中频率较高的字符位于较短的路径上,频率较低的字符位于较长的路径上。

百锦再的博客 2万+

数据结构 实验17:Huffman树和Huffman编码——学习理解哈夫曼树

这一期是完成最最最基本要求的Huffman树的创建和编码译码。越是深入学习,越会发现很多的需求和案例都是在身边的,脱离应用,单纯就写一个算法的实现感觉还是不那么能感受到学习的快乐,所以我后面还会有进阶版本的。

Supine_0的博客 2841

Warning-[INFL_DELTA] Too many events zero delay loop

项目场景: 运用VCS工具执行仿真的时候,遇到如下错误提示,但仿真还在继续。 Warning-[INFL_DELTA] Too many events Possible zero delay loop. Too many events in the simulation at time 0 fs. 问题描述: 为什么会有这个问题; 什么导致了这个问题; 原因分析: 1、为什么会有这个问题 由于竞争条件或编码风格不明确,可能会产生零延时回路,导致仿真挂起或仿真时间无限。 2、什么导致了这个问题 举

hh199203的博客 1万+

NVMe-MI --- Message Servicing Model(消息服务模型)

本文主要介绍NVMe-MI消息服务模型,两个主要类别是请求消息和响应消息。并介绍带外机制消息服务状态机。

智小星的博客 2012

赫夫曼编码Huffman的matlab编码实现

赫夫曼编码是我们经常使用的一种类型编码,它是一种即时码,有很多优点,下面我们使用matlab语言来实现huffman编码的过程。 首先,我们输入一组概率,这里以[0.512 0.128 0.128 0.032 0.128 0.032 0.032 0.008]为例。 P=[0.512 0.128 0.128 0.032 0.128 0.032 0.032 0.008];%输入 l=length(P)...

猫猫虫/的博客 3578

触摸延时灯课程设计

Multisim源文件下载: 实验名称:­­­­­­­­­­­­­­­­­­­ 课程设计1:触摸延时灯仿真设计 设计要求: 利用单稳态触发器设计触控延时灯,要求利用触发波形的边沿模拟触控点实现触发,触发后3秒灯亮,灯可以亮的时间可在5-10秒之间可调。 设计思路: 利用集成单稳态触发器CD4098设计简易的触摸延时灯电路。应用CD4098可以实现脉冲延时,原理图如下。4脚未触发信号输入端,可通过比较器对触摸产生的信号进行比较后再产生触发信号,使触发准确度得以提高。...

m0_54240221的博客 1万+

15、构造最优二叉树-赫夫曼(Huffman)树算法

一、基本概念 1、赫夫曼(Huffman)树又称最优二叉树或最优搜索树,是一种带权路径长度最短的二叉树。在许多应用中,常常赋给树中结点一个有某种意义的实数,称此实数为该结点的权。从树根结点到该结点之间的路径长度与该结点上权的乘积称为结点的带权路径长度(WPL),树中所有叶子结点的带权路径长度之和称为该树的带权路径长度,通常记为: 2、两结点间的路径:从一结点到另一结点所经过的结点序列;路径...

hopegrace的博客 9370

手把手教你用示波器抓取MIPI D-PHY波形:从LP11到HS Burst的完整信号解析

本文详细介绍了使用示波器精准捕获MIPI D-PHY信号的关键技巧,包括探头选择、示波器参数设置、信号状态解析及高级触发配置。通过实战案例和波形分析,帮助工程师快速识别从LP11到HS Burst的各种信号状态,解决常见的信号完整性问题,提升调试效率。

weixin_30471561的博客 560

msfvenom制作windows/linux/android/ios木马

msfvenom选项如下 -p, --payload<payload> 指定 payload(攻击荷载)。如果使用自定义payload,请使用'-'或者stdin指定。 -l, --list [module_typel列出指定模块的所有可用资源。模块类型包括:payloads, encoders, nops, all -n, --nopsled <length>为payload预先指定一个NOP滑动长度。 -f, --format <format>指定输出格式(使

Cwillchris的博客 2732

赫夫曼Huffman编码树

 可用一棵二叉编码树来表示一套具体的编码方案,其中每个节点的左右分支代表二进制中的0与1,用遍历经过的分支组成的二进制比特数列来表示信息。 编码:将信息转换为二进制形式的过程 解码:由二进制编码恢复原始信息的过程 一、Huffman树原理  由于使用遍历编码树所得的二进制序列来表示信息,故所遍历到的层次越深(所经过树的分支越多),则得到二进制序列越长。而为了编码的效率,一般寻求得到最短的二进制...

wjiaman 412

Python全栈入门到实战【基础篇 05】核心基础:Python的2种运行模式(交互式+命令行式)

Python代码运行模式详解:交互式与命令行式对比 摘要: Python提供两种核心运行模式:交互式(REPL)和命令行式(脚本式)。交互式模式适合快速测试语法,即时反馈结果,通过终端输入python启动,特点是无需保存、临时执行,适合验证小段代码逻辑。命令行式模式需将代码保存为.py文件后运行,适合开发完整程序,可重复执行和修改。两种模式各有优势:交互式便于学习调试,命令行式适合实际开发。掌握两种模式的使用场景和切换方法,是Python入门的关键技能,能显著提升学习效率。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 4554

赫夫曼编码

1、基本介绍 赫夫曼编码也翻译为 哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式, 属于一种程序算法 赫夫曼编码是赫哈夫曼树在电讯通信中的经典的应用之一。 赫夫曼编码广泛地用于数据文件压缩。其压缩率通常在20%~90%之间 赫夫曼码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,称之为最佳编码 2、原理剖析 通信领域中信息的处理方式1-定长编码 i like like like java do you like a java //

技术积累,技术分享 6265

Vue3 + 高德地图实现车辆电子围栏监控与报警

通过本文的实现,我们完成了一个通用的车辆电子围栏监控功能:支持多种围栏类型。支持进入/离开/双向报警。使用缓存机制避免重复告警。可与Vue3 + 高德地图无缝集成。在实际项目中,可以结合WebSocket 实时定位,实现车辆的实时监控 + 围栏告警系统🚀。

专注于前端开发与实战技巧,记录从零到一的学习与项目经验。分享 Vue3 / JavaScript / TypeScript / Flutter /Uniapp等前端技术,以及 性能优化、工程化、最佳实践。 1033

如何卸载Gazebo与重装

gazebo是一款关于车辆和无人机的仿真软件,本文大致介绍它是何物,以及他的安装和卸载方法,对于ROS开发者,本文有一定参考意义。

gongdiwudu的专栏 1万+
上一篇: DFS(深度优先遍历) & BFS:(广度优先遍历)
下一篇: 01背包,完全背包,多重背包,混合背包详解
Korpse
博客等级 码龄9年 115粉丝 25原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值