哈夫曼树编码长度怎么求_哈夫曼树编码长度怎么算

哈夫曼树编码长度怎么求_哈夫曼树编码长度怎么算经典算法: 哈夫曼编码1.哈夫曼树的基本概念从A结点到B结点所经过的分支序列叫做从A结点到B结点的路径;从A结点到B结点所经过的分支个数叫做从A结点到B结点的路径长度;从二叉树的根结点到二叉

经典算法: 哈夫曼编码
  1.哈夫曼树的基本概念

  从A结点到B结点所经过的分支序列叫做从A结点到B结点的路径;从A结点到B结点所经过的分支个数叫做从A结点到B结点的路径长度;从二叉树的根结点到二叉树中所有叶结点的路径长度之和称作该二叉树的路径长度。设二叉树有n个带权值的叶结点,定义从二叉树的根结点到二叉树中所有叶结点的路径长度与相应叶结点权值的乘积之和称作该二叉树的带权路径长度(WPL),即:

  WPL=sum_{i=1}^n w_i 	imes l_i

  其中,wi为第i个叶结点的权值,li为从根结点到第i个叶结点的路径长度。

  哈夫曼树编码长度怎么求_哈夫曼树编码长度怎么算

  (a)WPL = 1×2+3×2+5×2+7×2 = 32

  (b)WPL = 1×2+3×3+5×3+7×1 = 33

  (c)WPL = 7×3+5×3+3×2+1×1 = 43

  (d)WPL = 1×3+3×3+5×2+7×1 = 29

  具有最小带权路径长度的二叉树称作哈夫曼(Huffman)树(或称最优二叉树)。图(d)的二叉树是一棵哈夫曼树。

  定义:由给定的n个叶结点权值可以构造很多棵形态不同的二叉树,WPL值最小的二叉树称为哈夫曼树。

  要使一棵二叉树的带权路径长度WPL值最小,必须使权值越大的叶结点越靠近根结点。哈夫曼树构造算法为:

  (1)由给定的n个权值{w1,w2,…,wn}构造n棵只有根结点的二叉树,从而得到一个二叉树森林F={T1,T2,…,Tn}。

  (2)在二叉树森林F中选取根结点的权值最小和次小的两棵二叉树作为新的二叉树的左右子树构造新的二叉树,新的二叉树的根结点权值为左右子树根结点权值之和。

  (3)在二叉树森林F中删除作为新二叉树左右子树的两棵二叉树,将新二叉树加入到二叉树森林F中。

  (4)重复步骤(2)和(3),当二叉树森林F中只剩下一棵二叉树时,这棵二叉树就是所构造的哈夫曼树。

  2.哈夫曼编码问题

  将传送的文字转换为二进制字符0和1组成的二进制串的过程为编码。

  例:假设要传送的电文为ABACCDA,电文中只有A,B,C,D四种字符,若这四个字符采用表(a)所示的编码方案,则电文的代码为00 01 00 10 10 11 00,代码总长度为14。若这四个字符采用表(b)所示的编码方案,则电文的代码为0 110 0 10 10 111 0,代码总长度为13。

  哈夫曼树编码长度怎么求_哈夫曼树编码长度怎么算

  哈夫曼树可用于构造代码总长度最短的编码方案。具体构造方法如下:设需要编码的字符集合为{d1,d2,…,dn},各个字符在电文中出现的次数集合为{w1,w2,…,wn},以d1,d2,…,dn作为叶结点,以w1,w2,…,wn作为各叶结点的权值构造一棵二叉树,规定哈夫曼树中的左分支为0,右分支为1,则从根结点到每个叶结点所经过的分支对应的0和1组成的序列便为该结点对应字符的编码。代码总长度最短的不等长编码称之为哈夫曼编码。

  不等长编码不允许存在前缀码。前缀码的一个例子如:A为01,B为010。如编码存在前缀码,则译码会出现二义性。

  3.哈夫曼编码的实现

  一、哈夫曼编码的数据结构设计

  为了在构造哈夫曼树时能方便的实现从双亲结点到左右孩子结点的操作,在进行哈夫曼编码时能方便的实现从孩子结点到双亲结点的操作。设计哈夫曼树的结点存储结构为双亲孩子存储结构。采用仿真指针实现,每个结点的数据结构设计为:

  哈夫曼树编码长度怎么求_哈夫曼树编码长度怎么算

  从哈夫曼树求叶结点的哈夫曼编码实际上是从叶结点到根结点路径分支的逐个遍历,每经过一个分支就得到一位哈夫曼编码值。存放哈夫曼编码的数据元素结构为:

  哈夫曼树编码长度怎么求_哈夫曼树编码长度怎么算

  二、哈夫曼编码的算法实现

  typedef struct //哈夫曼树的结点结构

  {        int weight;                //权值

  int flag;  //标记

  int parent;                //双亲结点下标

  int leftChild;  //左孩子下标

  int rightChild;  //右孩子下标

  } HaffNode;

  typedef struct //存放哈夫曼编码的数据元素结构

  {        int bit[MaxN];  //数组

  int start;               //编码的起始下标

  int weight;               //字符的权值

  } Code;

  哈夫曼树构造算法如下:

  void Haffman(int weight[], int n, HaffNode haffTree[])

  //建立叶结点个数为n权值为weight的哈夫曼树haffTree

  {        int j, m1, m2, x1, x2;

  //哈夫曼树haffTree初始化。n个叶结点的哈夫曼树共有2n-1个结点

  for(int i = 0; i < 2 * n – 1 ; i++)

  {

  if(i < n)  haffTree[i].weight = weight[i];

  else        haffTree[i].weight = 0;

  haffTree[i].parent = -1;

  haffTree[i].flag   = 0;

  haffTree[i].leftChild = -1;

  haffTree[i].rightChild = -1;

  }

  //构造哈夫曼树haffTree的n-1个非叶结点

  for(i = 0;  i < n-1;  i++)

  {        m1 = m2 = MaxValue;         x1 = x2 = 0;

  for(j = 0;   j < n+i;  j++)

  {        if(haffTree[j].weight < m1 && haffTree[j].flag == 0)

  {        m2 = m1;

  x2 = x1;

  m1 = haffTree[j].weight;

  x1 = j;

  }

  else if(haffTree[j].weight < m2 && haffTree[j].flag == 0)

  {

  m2 = haffTree[j].weight;

  x2 = j;

  }

  }

  //将找出的两棵权值最小的子树合并为一棵子树

  haffTree[x1].parent  = n+i;

  haffTree[x2].parent  = n+i;

  haffTree[x1].flag    = 1;

  haffTree[x2].flag    = 1;

  haffTree[n+i].weight = haffTree[x1].weight+haffTree[x2].weight;

  haffTree[n+i].leftChild = x1;

  haffTree[n+i].rightChild = x2;

  }

  }

  哈夫曼编码算法如下:

  void HaffmanCode(HaffNode haffTree[], int n, Code haffCode[])

  {

  Code *cd = (Code *)malloc(sizeof(Code));

  int i, j, child, parent;

  //求n个叶结点的哈夫曼编码

  for(i = 0; i < n; i++)

  {

  cd->start = n-1;

  cd->weight = haffTree[i].weight;

  child = i;

  parent = haffTree[child].parent;

  //由叶结点向上直到根结点

  while(parent != -1)

  {

  if(haffTree[parent].leftChild == child)

  cd->bit[cd->start] = 0;

  else                     cd->bit[cd->start] = 1;

  cd->start–;

  child = parent;

  parent = haffTree[child].parent;

  }

  for(j = cd->start+1; j < n; j++)

  haffCode[i].bit[j] = cd->bit[j];

  haffCode[i].start  = cd->start + 1;

  haffCode[i].weight = cd->weight;

  }

  }

  最后是测试用例

  设有字符集{A, B, C, D},各字符在电文中出现的次数集为{1, 3, 5, 7},设计各字符的哈夫曼编码。

  #include <stdio.h>

  #include <stdlib.h>

  #define MaxValue 10000

  #define MaxBit 4

  #define MaxN 100

  void main(void)

  {        int i, j, n = 4;

  int weight[] = {1,3,5,7};

  HaffNode *myHaffTree = (HaffNode *)malloc(sizeof(HaffNode)*(2*n-1));

  Code *myHaffCode = (Code *)malloc(sizeof(Code)*n);

  if(n > MaxN)

  {        printf("给出的n越界,修改MaxN值!

  ");

  exit(0);

  }

  Haffman(weight, n, myHaffTree);

  HaffmanCode(myHaffTree, n, myHaffCode);

  //输出每个叶结点的哈夫曼编码

  for(i = 0; i < n; i++)

  {        printf("Weight = %d   Code = ", myHaffCode[i].weight);

  for(j = myHaffCode[i].start; j < n; j++)

  printf("%d", myHaffCode[i].bit[j]);

  printf("

  ");

  }

  }

激活谷谷主为您准备了激活教程,为节约您的时间请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/96172.html

(0)
上一篇 2024年 5月 23日
下一篇 2024年 5月 23日

相关推荐

  • 反相积分器实验报告怎么写_反相积分器实验报告怎么写的

    反相积分器实验报告怎么写_反相积分器实验报告怎么写的一些不能再基础的模拟电路思考(17)大家可能对积分器的作用不太了解。在另一个专栏里面稍微分析了一下反相积分器的一些特点,是关于电路参数级别的。但是积分器到底能够起一些什么样的作用,在哪里出现是陌生的。仍然以理想反相积分器为例。反相积分器其时域特征为:频域特征为:时域特征能够清

    2024年 5月 26日
  • bashgcc未找到命令_bash:未找到命令

    bashgcc未找到命令_bash:未找到命令-bash: make: 未找到命令 gcc安装-bash: make: 未找到命令gcc官方有yum源吗?没有就算了,都到个安装开发工具的命令,有make命令,可以用了如何在CentOS 8上安装GCC开发工具(De

    激活谷笔记 2024年 5月 29日
  • 单片机c语言要学到什么程度_单片机c语言要学到什么程度才能学

    单片机c语言要学到什么程度_单片机c语言要学到什么程度才能学c语言要学到什么程度可以学单片机?本人大一电子信息工程专业学生,第一个学期学校没开专业课,下学期有c语言和电路分析。单片机大三才有。因为比较感兴趣,这个学期初步学了multisim,画了些简单的电路图,学了立创eda和ad,制了几个简单的pcb板,也学了焊接,焊了时钟,音响,收音机。打算寒假在家学

    2024年 5月 26日
  • ubuntu和xubuntu_最好的轻量级ubuntu

    ubuntu和xubuntu_最好的轻量级ubuntu10个最佳的基于Ubuntu的Linux发行版Ubuntu可以说是最受欢迎和使用最广泛的 Linux 发行版之一,因为它具有经典的 UI、稳定性、用户友好性以及包含超过50,000 个软件包的丰富存储库。此外,强烈建议尝试尝

    2024年 5月 14日
  • 控件开发工具怎么用不了

    控件开发工具怎么用不了今天分享如何利用Word开发工具中的空间来实现上述功能。·选择好下拉菜单和付款框。·首先打开文档,调出开发工具,在“文件”选项中找到“自定义功能区”,勾选“开发工具”选项,然后点击“确定”,添加一个选项卡。·将光标移动到需要插入空间的位置,点击“开发工具

    激活谷笔记 2024年 5月 17日
  • 函数 已有主体怎么写出来图片_函数 已有主体怎么写出来图片大全

    函数 已有主体怎么写出来图片_函数 已有主体怎么写出来图片大全全套函数图表大全 函数图表表达引言:函数图表是数学学科中重要的工具和表达形式之一。通过函数的图表,我们可以直观地观察函数的特性和变化规律。本文将详细介绍函数图表的基本概念、常见分类和示例,并为读者提供一

    激活谷笔记 2024年 5月 27日
  • 网站seo入门基础教程书籍有哪些

    网站seo入门基础教程书籍有哪些在这个互联网高速发展的时代,我们都习惯了在网站寻找自己想要的资源和答案,但是无论网络是多么的方便,我们依然离不开纸质书籍,忘不了那书香油墨味,所以在这里给大家推荐几本我个人初学seo时学习的入门书籍。第一本第一本:《搜索引擎技术基础

    激活谷笔记 2024年 5月 17日
  • uniapp面试题_uniapp路由传参有几种方式

    uniapp面试题_uniapp路由传参有几种方式Uniapp路由传递数据在 UniApp 中,可以使用路由参数传递来在页面之间传递数据。UniApp提供了多种传递参数的方式,下面列举了几种常用的方法:1. Query 参数传递: 在 `uni.navigateTo

    激活谷笔记 2024年 5月 10日
  • uniapp开发小程序源码_在哪里去买uniapp源码

    uniapp开发小程序源码_在哪里去买uniapp源码推荐一个uniapp写的商城源码uniapp开发的商城有什么优势? 1 开发成本低,不止开发成本,招聘、管理、测试各方面成本都大幅下降。 2 学习成本低,基于通用的前端技术栈,采用vue语法+小程序api,无

    2024年 5月 15日
  • coss协议与zigbee_coss协议与zigbee的区别

    coss协议与zigbee_coss协议与zigbee的区别智能家居的CoSS协议和ZigBee协议有什么区别?CoSS特点距离远:CoSS可以实现800米超远距离传输,800米范围内的设备可以实现畅通的数据传递,以智能网关设备为核心形成一个星型网络覆盖区。功耗

    激活谷笔记 2024年 5月 30日
  • pycharm的作用_pycharm配置python吗

    pycharm的作用_pycharm配置python吗pycharm如何配置编译环境_python不配置环境变量会怎样大家好,又见面了,我是你们的朋友全栈君。 随便打开一个.py文件时,右上角三角形运行按钮不能选中,需要配置编译环境在这里插入图片描述 配置编译环境有两个部分:1、添加编译器(interpret

    2024年 5月 9日
  • 积分运算电路和微分运算电路的区别与联系_积分运算电路和微分运算电路的区别与联系

    积分运算电路和微分运算电路的区别与联系_积分运算电路和微分运算电路的区别与联系全国服务热线:18923864027积分运算电路与微分运算电路介绍积分运算电路1.一般的积分运算电路反相积分运算电路是常用的积分运算电路。如下图所示。电路分析:输入电阻为R,放大倍数取决于R、C的大小。为保证集成运放输入级差分放大电路的对称性,电阻R&

    2024年 5月 30日
关注微信