哈夫曼编码

2023-10-26

哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫Huffman编码(有时也称为霍夫曼编码)。

下面是用C语言实现的简单的哈夫曼编码实现,要实现编码,首先得创建哈夫曼树(也叫最优二叉树)。

哈夫曼树就是带权路径长度(WPL)最小的二叉树,而权路径长度(WPL)指的是出现频率*其到根节点的长度。最后使出现平率高的越靠近根节点。

哈夫曼编码的优点便是降低重复的码值,实现无损压缩。

#include <stdio.h>
#include <stdlib.h>
//结构体创建节点 
typedef struct{
char word;
int weight,left,right,parent;
int *code;
}HuffNode;
//初始化森林(对节点与权值进行初始化)
int n;
void StartHuffTree(HuffNode * F){
	int i,w;
	char ch;
	printf("请输入字符与权重(空格间隔,回车结束):\n");
	for(i=0;i<n;i++){
		printf("第%d个节点:",i+1); 
		scanf("%s",&ch);
		scanf("%d",&w);
		F[i].word=ch;
		F[i].weight=w;
		F[i].left=F[i].right=F[i].parent=-1;
		F[i].code=NULL;
	}
	printf("----------------------------------------------------\n");
}


//创建哈夫曼树  (创建哈夫曼树,最优二叉树)
void CreatHuffTree(HuffNode * F){ 
	printf("创建哈弗曼树:\n");
	int i,j,k1,k2; 
	//循环n-1次创建树的双亲 
	for(i=0;i<n-1;i++){
	//k1,k2找到可以作为子树的树 
		for(k1=0;k1<n+i&&F[k1].parent!=-1;k1++);
		for(k2=k1+1;k2<n+i&&F[k2].parent!=-1;k2++);
		//循环 整个森林,使得k1,k2为最小的次小的2颗树 
		for(j=k2;j<n+i;j++){
			if(F[j].parent==-1){
			if(F[j].weight<F[k1].weight){
				k2=k1;
				k1=j;
			}
			else if(F[j].weight<F[k2].weight){
				k2=j;
			}
		}
	} 
	//在第n+i节点 上创建k1,k2的双亲 
	F[n+i].word='x';
	F[n+i].weight=(F[k1]).weight+(F[k2]).weight;
	F[n+i].left=k1;
	F[n+i].right=k2;
	F[n+i].parent=-1;
	F[n+i].code=NULL;
	F[k1].parent=n+i;
	F[k2].parent=n+i;
	// printf("%d",F[n+i].parent); 
	// getchar();
	// 
}
//判断创建的树是否正确 
for(j=0;j<7;j++){
	printf("%4c",F[j].word);
	printf("%4d",F[j].weight);
	printf("%4d",F[j].left);
	printf("%4d",F[j].right);
	printf("%4d\n",F[j].parent);
}
	printf("-----------------------------------------------------\n");
}

//对哈弗曼树进行编码 
void CreatCode(HuffNode * F){
	printf("哈弗曼树编码:............\n");
	int i,pa,c;
	int *p;
for(i=0;i<n;i++){
	F[i].code=p=(int *)malloc(n*sizeof(int));
	p[0]=0;
	c=i;
	while(F[c].parent!=-1){
		pa=F[c].parent;
		if(F[pa].left==c){
			p[++p[0]]=0;
		}else{
			p[++p[0]]=1;
		}
		c=pa;
	
	}
}
}


void PrintHuffTree(HuffNode * F){
	printf("输出哈夫曼编码:\n");
	for(int i=0;i<n;i++){
		printf("%4c",F[i].word);
		printf("   ");
	for(int j=F[i].code[0];j>0;j--){

		printf("%d",F[i].code[j]);
	}
		printf("\n");
	}
}
int main(void)
{
	printf("输入叶子节点个数:");
	scanf("%d",&n);
	//初始化 
	HuffNode * F=(HuffNode *)malloc((2*n-1)*sizeof(HuffNode));
	StartHuffTree(F); 
	//创建哈夫曼树
	CreatHuffTree(F); 
	//编码
	CreatCode(F);
	//输出
	PrintHuffTree(F); 
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

哈夫曼编码 的相关文章

  • 哈希表与树的介绍

    前言 该篇文章 主要带我们认识什么哈希表和树 为我们在研究各个数据结构的实现及扩展算法 有个基本的认识 哈希表 特点 数组 寻址容易 数据连续存储空间 链表 插入与删除容易 放在堆内存中对象 存储并不连续 哈希表 寻址容易 插入删除也容易的
  • 二叉树建立

    结束二叉树输入 如何结束创建二叉树的输入那 把二叉树补全 前序 输入 AB C 中序 B A C 后序 B CA 输出结果如下 代码如下 include
  • 数据结构中二叉树实现及部分操作

    谈二叉树之前 我们先来看看树的定义 树 由N N gt 0 个结点构成的集合 对N gt 1的树 1 有一个特殊的结点 称为根结点 根节点没有前驱结点 2 除根节点外 其余结点被分成M M gt 0 个互不相交的集合T1 T2 Tm 其中每
  • 计算二叉树的第k层中所有叶子结点个数

    计算二叉树的第k层中所有叶子结点个数 Time Limit 1000MS Memory Limit 65535K 题型 编程题 语言 无限制 描述 二叉链表表示的二叉树 按先序次序输入二叉树中结点的值 字符表示空树 构造二叉链表表示的二叉树
  • 二叉树采用二叉链表存储,求树的结点个数

    typedef struct BiTNode ElemType data struct BiTNode lchild rchild BiTNode BiTree void PrePrder BiTree T int num if T NUL
  • 【leetcode】----102二叉树的层序遍历

    102二叉树的层序遍历 给你一个二叉树 请你返回其按 层序遍历 得到的节点值 即逐层地 从左到右访问所有节点 示例 二叉树 3 9 20 null null 15 7 3 9 20 15 7 返回其层次遍历结果 3 9 20 15 7 BF
  • java实现赫夫曼树以及赫夫曼编码和解码(用byte[])

    首先对于赫夫曼编码有个大概的理解 赫夫曼编码 Huffman Coding 又称霍夫曼编码 是一种编码方式 可变字长编码 VLC 的一种 Huffman于1952年提出一种编码方法 该方法完全依据字符出现概率来构造异字头的平均长度最短的码字
  • 二叉排序树与平衡二叉树(BST&AVLT)

    平衡二叉树的一些操作 平衡二叉树相对于二叉排序树来说是二叉排序树的一个优化版 避免了二叉排序树中的极端情况 想更好的理解还是要结合图片自己动手做做QwQ 这里写的是双平衡 双旋转版 并非LL RR LR RL四种特殊情况单独处理 平衡二叉树
  • Console.WriteLine打印中文为何出乱码?

    因为你当前环境代码页是437 是美国英语的字符编码 你把你环境设置成936就是简体中文字符编码环境了 你当前的是这个 Console OutputEncoding Encoding GetEncoding 437 设置成这样就支持中文编码了
  • 【数据结构】 二叉树面试题讲解->壹

    文章目录 引言 相同的树 https leetcode cn problems same tree description 题目描述 示例 示例一 示例二 示例三 题目解析 代码实现 另一棵树的子树 https leetcode cn pr
  • Java 【数据结构OJ题十道】—— 二叉树篇1

    文章目录 一 检查两棵二叉树是否相同 二 另一棵二叉树的子树 三 二叉树的构建及遍历 四 序列化二叉树和反序列化二叉树 难 五 二叉树创建字符串 六 二叉树前序非递归遍历实现 七 二叉树中序非递归遍历实现 八 二叉树后序非递归遍历实现 九
  • 剑指 Offer 27. 二叉树的镜像 -- 递归

    0 题目描述 leetcode原题链接 剑指 Offer 27 二叉树的镜像 1 递归算法 根据二叉树镜像的定义 考虑递归遍历 d f s mathrm dfs dfs 二叉树 交换每个节点的左 右子节点 即可生成 二叉树的镜像 递归解析
  • 08黑马笔记之栈的应用_就近匹配(括号)

    08黑马笔记之栈的应用 就近匹配 括号 思想 前提 使用栈的链式存储来实现 1 遇到左括号就放进栈中 再遇到右括号就将左括号从栈中删除 若栈中没有元素或者不是左括号 则说明右括号匹配失败 以上是判断右括号不匹配的 下面是判断左括号不匹配 2
  • 转:使用DOS命令chcp查看windows操作系统的默认编码以及编码和语言的对应关系

    代码页是字符集编码的别名 也有人称 内码表 早期 代码页是IBM称呼电脑BIOS本身支持的字符集编码的名称 当时通用的操作系统都是命令行界面系统 这些操作系统直接使用BIOS供应的VGA功能来显示字符 操作系统的编码支持也就依靠BIOS的编
  • 【数据结构】树与二叉树

    文章目录 树型结构 什么是树型结构 树型结构的概念 树的表示形式 树的应用 二叉树 二叉树的概念 两种特殊的二叉树 二叉树的性质 二叉树性质练习 练习一 解析 练习二 解析 练习三 解析 练习四 解析 总结 树型结构 什么是树型结构 树是一
  • python二叉树类定义,列表转二叉树,leetcode本地调试

    如果想用本地IDE调试leetcode上的题目 可以使用以下辅助类 二叉树类定义 Definition for a binary tree node class TreeNode def init self x self val x sel
  • 用 Java 实现的八种常用排序算法

    八种排序算法可以按照如图分类 前置知识 1 算法稳定性 在一个序列中 能保证两个相等的数 经过排序之后 其在序列的前后位置顺序不变 A1 A2 排序前 A1 在 A2 前面 排序后 A1 还在 A2 前面 2 时间复杂度 时间复杂度是用于衡
  • setlocale()/_wsetlocale()函数的使用

    在C运行库提供的多字节字符 宽字符转换函数 mbstowcs wcstombs 中 需要用到全局变量locale locale encoding 以指定多字节字符的编码类型 1 功能 用来定义全局变量 locale locale encod
  • JAVA实现二叉树的前、中、后序遍历(递归与非递归)

    最近在面试中遇到过问到二叉树后序遍历非递归实现的方法 之前以为会递归的解决就OK 看来还是太心存侥幸 在下一次面试之前 特地整理一下这个问题 首先二叉树的结构定义 java代码如下 public class Node private int
  • 剑指 Offer(第2版)面试题 34:二叉树中和为某一值的路径

    剑指 Offer 第2版 面试题 34 二叉树中和为某一值的路径 剑指 Offer 第2版 面试题 34 二叉树中和为某一值的路径 解法1 深度优先搜索 剑指 Offer 第2版 面试题 34 二叉树中和为某一值的路径 题目来源 47 二叉

随机推荐

  • 认识BLE 5协议栈 —— 逻辑链路控制与适配协议层(L2CAP,Logical Link Control and Adaptation Protocol)

    转自 http www sunyouqun com 2017 04 understand ble 5 stack l2cap layer 逻辑链路控制与适配协议通常简称为L2CAP Logical Link Control and Adap
  • 第十届蓝桥杯(明码+迷宫)

    第十届蓝桥杯省赛C B组 明码 汉字的字形存在于字库中 即便在今天 16点阵的字库也仍然使用广泛 16点阵的字库把每个汉字看成是16x16个像素信息 并把这些信息记录在字节中 一个字节可以存储8位信息 用32个字节就可以存一个汉字的字形了
  • mybatis-plus动态表名实现

    mybatis plus动态表名实现 1 使用场景 一个mybatis entity 对应多张表 表明不同的表 gt 多张表结构一致只有表名称不同 在使用时 可以动态映射表名称 比如 按照时间分表 某些业务冷热数据分离后数据存在不同的表中等
  • 服务器与云服务器传输文件,服务器与云服务器传输文件

    服务器与云服务器传输文件 内容精选 换一换 安装传输工具在本地主机和Windows云服务器上分别安装数据传输工具 将文件上传到云服务器 例如QQ exe 在本地主机和Windows云服务器上分别安装数据传输工具 将文件上传到云服务器 例如Q
  • 阿里云OSS进行文件下载时,报NOSuchKeys: com.aliyun.oss.OSSException: The specified key does not exist.

    OSS文件下载 bucketName bucket的名称 objectName 保存文件时 OSS服务器返回给我们的url path 下载到本地的路径 OSSClient client new OSSClient endpoint acce
  • 钟汉良日记:啥都不会做什么副业好?

    2022年9月14日 周三 天气阴 服务的老板 昨天把搜狐号和网易号给我搞定后 我就把之前写的文章都同步更新到这两个自媒体平台上 今天再查看 网易号上发布的文章 排名也上了百度首页 你看 自媒体平台发布文章效果就是这么好 现在已经不是过去那
  • 用nginx Rtmp Module自建直播服务器

    下载源码 首先准备好源码和常用编译工具 gcc之类的 mkdir opt git 这里我偷懒直接把源码下载到这了 大家自行找地方 cd opt git git clone https github com arut nginx rtmp m
  • Java_经典算法之桶排序

    一 桶排序介绍 桶排序是计数排序的升级版 它利用了函数的映射关系 高效与否的关键就在于这个映射函数的确定 为了使桶排序更加高效 我们需要做到这两点 在额外空间充足的情况下 尽量增大桶的数量 使用的映射函数能够将输入的 N 个数据均匀的分配到
  • matlab在循环时如何跳过几个数,matlab如何得到一个数组的行数和列数, matlab判断数组的长度

    1 matlab在循环时如何跳过几个数 eg 循环输出1到10 但需要跳过5 for i 1 4 6 10 fprintf d n i end 2 matlab中如何得到数组的行数和列数 eg 创建一个2 3的0向量 并判断行数和列数 m
  • C++ const

    class A private const int a 常对象成员 可以使用初始化列表或者类内初始化 public 构造函数 A a 0 A int x a x 初始化列表 const可用于对重载函数的区分 int getValue 普通成
  • ubuntu编译caffe

    https blog csdn net weixin 42068754 article details 103386379 spm 1001 2101 3001 6661 1 utm medium distribute pc relevan
  • conda创建的虚拟环境和Pycharm创建的虚拟环境有什么区别。

    问题描述 刚开始学习深度学习时 不同项目都需要安装不同的库 有时为了方便 不同的项目就使用了独立的虚拟环境 这样在加载库时比较快一些 如果所有项目的库都安装在base下 可能会出现版本不匹配之类的问题 所以 一开始使用的conda创建的虚拟
  • 内网穿透两种方式

    一 内网穿透引入 你是否被以下问题所困扰 我想装个B让其他同学在外网访问我的程序 应该怎么办 接了个小外包 给客户演示Demo没有站点怎么办 做微信 支付宝支付等其他第三方平台的功能 没有外网回调地址 应该怎么办 内网穿透 又叫NAT穿透
  • ODOO 安装

    ODOO 安装 对初学者而言 ODOO 的安装是横在面前的第一道坎 必须过的 和几年前情况不同 最近几年 ODOO在安装方面已经大幅改进 不需要太专业的技能也能完成安装过程 下面先说说大致的安装过程 有空再补上详细的图片和步骤 准备工作 1
  • [2017年第八届真题] 分巧克力

    题目 传送门 思路 二分答案 写个check函数 对每个mid进行检查可行性 结果再检查能不能切割出k块或以上的 l l 的巧克力 不能的话 要 1 Code include
  • 七、Hadoop系统应用之搭建Hadoop高可用集群(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)

    Hadoop集群搭建前安装准备参考 一 Hadoop系统应用之安装准备 一 超详细步骤指导操作 WIN10 VMware Workstation 15 5 PRO CentOS 6 7 一 Hadoop系统应用之安装准备 二 超详细步骤指导
  • 大话赛宁云

    如今 随着数字时代的飞速发展 安全漏洞存在于网络空间中 对系统造成极大的安全隐患 为网络攻击者的恶意入侵提供了捷径 对此 解决这一困境 要秉承 快速 自动 安全 的解决标准 首先需要高技术手段的支持 实施常态化演练 及时发现安全漏洞 测评危
  • 暑期必须要学习的52个Python+OpenCV实战项目

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 有个粉丝前几天问我 本人小白一枚 看了很多深度学习 机器学习以及图像处理等视频和书之后 理论有一些长进 但是实际运用能力不足 从反面也是由于理论认识不足所致 所以想问问有
  • 完整的vuejs + django 前后端分离项目实践(登录,注册,权限控制,可视化)

    完整的vuejs django 前后端分离项目实践 登录 注册 权限控制 可视化 vuejs是一个流行的前端框架 django是一个python非常流行的web框架 在某期的作业中 需要基于它两实现一个前端后分离 并且拥有权限管理的系统 声
  • 哈夫曼编码

    哈夫曼编码 Huffman Coding 又称霍夫曼编码 是一种编码方式 哈夫曼编码是可变字长编码 VLC 的一种 Huffman于1952年提出一种编码方法 该方法完全依据字符出现概率来构造异字头的平均长度最短的码字 有时称之为最佳编码