一 、目的:
1.    掌握Huffman树的概念、存储结构;
2.    掌握建立Huffman树和Huffman编码的方法;
二 、环境:
operating system version:Win11
CPU instruction set:  x64
Integrated Development Environment:Viusal Studio 2022
三 、内容:
利用动态分配数组存储赫夫曼树,设计一组输入数据(假定为一组整数),能够对其进行如下操作:
1)创建一个新的顺序表,实现动态空间分配的初始化
2)对输入的数据构造成一棵 Huffman 树;
3)根据生成的 Huffman 树进行 Huffman 编码
4)实现对输入数据的 Huffman 编码输出 。
四 、要求:
1) 实现 Huffman 树的生成
2) 完成 Huffman 编码的输出 。
五 、步骤:
1. 程序:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>  using namespace std;
typedef char ElemType;
typedef struct {  ElemType elem;  unsigned int weight;  unsigned int parent, lchild, rchild, tag;
}HTNode, * HuffmanTree;
typedef char** HuffmanCode;  typedef int Status;
typedef struct weight
{  char elem;  unsigned int m_weight;
}Weight;   void Select(HuffmanTree HT, int n, int& s1, int& s2)
{  int i;  s1 = s2 = 0;  for (i = 1; i <= n; i++) {  if (HT[i].weight < HT[s2].weight && HT[i].parent == 0 && s2 != 0) {  if (HT[i].weight < HT[s1].weight) {  s2 = s1;    s1 = i;  }  else s2 = i;  }  if ((s1 == 0 || s2 == 0) && HT[i].parent == 0) {  if (s1 == 0) s1 = i;  else if (s2 == 0) {  if (HT[i].weight < HT[s1].weight) {  s2 = s1;  s1 = i;  }  else s2 = i;  }   }    }   if (s1 > s2) {  i = s1; s1 = s2; s2 = i;  }
}  void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, Weight*& w, int n) {  // w存放n个字符的权值(均>0),构造哈夫曼树HT,  // 并求出n个字符的哈夫曼编码HC  //本函数实现选择方式:从左往右选择两个小权值结点,结点信息在前面的为左子树,其后为右子树  int i, j, m, s1, s2;  char* cd;  int p;  int cdlen;  if (n <= 1) return;  m = 2 * n - 1;  HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));   // 0号单元未用  for (i = 1; i <= n; i++) { //初始化  HT[i].elem = w[i - 1].elem;  HT[i].weight = w[i - 1].m_weight;  HT[i].parent = 0;  HT[i].lchild = 0;  HT[i].rchild = 0;  }  for (i = n + 1; i <= m; i++) { //初始化  HT[i].weight = 0;  HT[i].parent = 0;  HT[i].lchild = 0;  HT[i].rchild = 0;  }  printf("\n哈夫曼树的构造过程如下所示:\n");  printf("HT初态:\n  结点  weight  parent  lchild  rchild");  for (i=1; i<=m; i++)  printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight,  HT[i].parent,HT[i].lchild, HT[i].rchild);  getchar();  for (i = n + 1; i <= m; i++) {     // 建哈夫曼树  // 在HT[1..i-1]中选择parent为0且weight最小的两个结点,  // 其序号分别为s1和s2。  Select(HT, i - 1, s1, s2);  HT[s1].parent = i;  HT[s2].parent = i;  HT[i].lchild = s1;  HT[i].rchild = s2;  HT[i].weight = HT[s1].weight + HT[s2].weight;  printf("\nselect: s1=%d   s2=%d\n", s1, s2);  printf("  结点  weight  parent  lchild  rchild");  for (j=1; j<=i; j++)  printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,  HT[j].parent,HT[j].lchild, HT[j].rchild);  getchar();  }  //------无栈非递归遍历哈夫曼树,求哈夫曼编码  HC = (HuffmanCode)malloc((n + 1) * sizeof(char*));  cd = (char*)malloc((n + 1) * sizeof(char)); // 分配求编码的工作空间  p = m;  cdlen = 0;  for (i = 1; i <= m; ++i)  // 遍历哈夫曼树时用作结点状态标志  HT[i].tag = 0;  while (p) {  if (HT[p].tag == 0) { // 向左  HT[p].tag = 1;  if (HT[p].lchild != 0) { p = HT[p].lchild;  cd[cdlen++] = '0'; }  else if (HT[p].rchild == 0) {  HC[p] = (char*)malloc((cdlen + 1) * sizeof(char));  cd[cdlen] = '\0';  strcpy(HC[p], cd);  }  }  else if (HT[p].tag == 1) {        // 向右  HT[p].tag = 2;  if (HT[p].rchild != 0) { p = HT[p].rchild;  cd[cdlen++] = '1'; }  }  else {   // HT[p].weight==2,退回退到父结点,编码长度减1  HT[p].tag = 0; p = HT[p].parent; --cdlen;  }  }
}   void OutputHuffmanCode(HuffmanTree HT, HuffmanCode HC, int n)
{  int i;  printf("\nnumber---element---weight---huffman code\n");  for (i = 1; i <= n; i++)  printf("  %d        %c         %d        %s\n", i, HT[i].elem, HT[i].weight, HC[i]);
}  int  main()
{  HuffmanTree HT;  HuffmanCode HC;  Weight* w;  char c;     // the symbolizes;  int i, n;      // the number of elements;   int wei;    // the weight of a element;   printf("请输入准备构建哈夫曼树的结点数:");  cin >> n; //cout<<endl;  w = (Weight*)malloc(n * sizeof(Weight));  for (i = 0; i < n; i++)  {  printf("请输入结点编号与对应的权值(node weight):");  scanf("%1s%d", &c, &wei);  w[i].elem = c;  w[i].m_weight = wei;  }  HuffmanCoding(HT, HC, w, n);  OutputHuffmanCode(HT, HC, n);  }

2.程序结果:

1)程序运行,我使用的测试数据如下所示:

2)首先按照要求完成了哈夫曼树的构建:

3)最终完成哈夫曼编码,结果与预期一致。

六 、小结:

此次是关于哈夫曼树的编程与实现,通常给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

我先输入了权值的 n 个结点,并且在构建哈夫曼树时我采用了如下办法:首先在 n 个权值中选出两个最小的权值,对应的两个结点组成一个新的二叉树,且新二叉树的根结点的权值为左右孩子权值的和;在原有的 n 个权值中删除那两个最小的权值,同时将新的权值加入到 n–2 个权值的行列中,以此类推;重复上述过程,直到所以的结点构建成了一棵二叉树为止,就得到了哈夫曼树。通常查找权重值最小的两个结点的思想是:从树组起始位置开始,首先找到两个无父结点的结点(说明还未使用其构建成树),然后和后续无父结点的结点依次做比较,有两种情况需要考虑:如果比两个结点中较小的那个还小,就保留这个结点,删除原来较大的结点;如果介于两个结点权重值之间,替换原来较大的结点。最终实现了描述的功能。

Huffman 编码的编程与实现 C语言相关推荐

  1. HuffMan编码C语言实现

    HuffMan编码C语言实现 实现了一种编码方式,和两种解码方式. 解码一种使用的是叶子回溯根. 一种使用了从根遍历过程. 代码: HuffManEncoding // // Created by Z ...

  2. huffman编码压缩c语言,用Huffman编码对文件进行压缩的C语言实现

    本文介绍了采用Huffman编码对ASCII码文件进行压缩的基本原理,并用C语言程序实现了这个压缩过程.文中给出了比较完整的C语言程序代码,可以直接用于调试实验. 福 建电 脑 21 0 2年第 1期 ...

  3. huffman编码译码器用c语言,基于哈弗曼编码的数据压缩C语言实现

    haod 摘要 数据压缩技术是一项重要实用的信息技术.信息时代的到来,信息量迅速增长,使得数据压缩也显得越来越重要.数据压缩有多种编码方法,大致可分为无损压缩编码和有损压缩编码.其中,Huffman ...

  4. Huffman 编码的实现(C语言)

    Huffman 编码 具体原理及定义请百度,下面直接进行实现.具体实现过程是: 统计若干字符出现的频率,将其按频率(权重)升序存放进队列中,每次从队列中取两个结点合成一颗二叉树,这两个结点的根节点是取 ...

  5. 基于Huffman编码的C语言解压缩文件程序

    #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h>//极大 ...

  6. 数据压缩实验三:用c语言实现Huffman编码和压缩效率分析

    实验原理: 1.Huffman编码 Huffman编码是一种无失真的编码方式,是可变字长编码(VLC)的一种. Huffman编码基于信源的概率统计模型,它的基本思路是: 出现概率大的信源符号编长码, ...

  7. Huffman编码的C语言实现

    实验原理 Huffman 编码 (1) Huffman Coding (霍夫曼编码)是一种无失真编码的编码方式,Huffman 编码是可变字长编码(VLC)的一种. (2)Huffman 编码基于信源 ...

  8. 霍夫曼(Huffman)编码算法详解之C语言版

    一.Huffman编码 霍夫曼(Huffman)树是一类带权路径长度最短的二叉树树.Huffman树的一个非常重要的应用就是进行Huffman编码以得到0-1码流进行快速传输. 在电报收发等数据通讯中 ...

  9. huffman图像编码C语言,Huffman编码 数据结构 C语言

    为解决广大童鞋的数据结构实验问题写下本文:(只做参考哦.) 实验要求: Huffman编码(二叉树) l实验目的:熟练掌握二叉树应用(Huffman编码)的基本算法实现. l实现功能:对输入的一串电文 ...

最新文章

  1. Hadoop学习之MapReduce(一)
  2. 使用Docker中的mysql
  3. mallcloud商城基于SpringBoot2.x
  4. 9.5noip模拟试题
  5. 鸿蒙安卓生态已经非常完善,鸿蒙前进一小步,生态却完善一大步,解决了替换安卓的第一个问题...
  6. qqxml图片代码_分享三款高级qqxml消息卡片代码
  7. 微信小程序- MQTT模拟器
  8. 安装打印机时出现无法安装,打印处理器不存在
  9. 软件测试入门知识,Linux系统基础教程——带你玩转Linux(五)
  10. Ubuntu 18.04 LTS上编译安装BCC
  11. Nova8pro自动调节亮度忽亮忽暗问题
  12. 什么是可视化?数据可视化有什么作用和价值
  13. 地震了!最好直接砸死我!
  14. python爬取百度迁徙动态图_爬取动态图片—以百度图片为例
  15. 2021国产数据库领域最具商业合作价值企业盘点
  16. STM32MP157系列教程连载-Linux应用开发篇1:STM32MP1微处理器之Ubuntu安装与体验
  17. 哲学家进餐_我如何通过预算学习计划进餐
  18. 软件测试常用术语总结
  19. 上拉电阻和下拉电阻判断
  20. [python]编写程序产生 ISBN 号的校验位。

热门文章

  1. c语言奇偶归一猜想最大数,C语言:奇偶归一猜想
  2. python-字典key的获取
  3. Hash碰撞如何解决
  4. 模糊c均值聚类算法的c++实现
  5. Python实现条形码生成
  6. flume系列之:hdfs.timeZone设置中国北京或上海时区
  7. socket网络编程及通过socket接口实现一个自我通信的简易UDP服务器
  8. 基于深度学习的端到端的车牌检测与识别
  9. 【usb】linux内核USB键盘驱动解析--普通键值上报及转化
  10. EXCEL截取单元格内部分字符串、根据前一列某些字符替换本列的某几个字符的操作