C++实现:霍夫曼编码

C++ 哈夫曼编码 1.哈夫曼编码的结点类: struct HuffmanNode { int weight; // 权重,出现的次数或者频率 char ch; // 存储符号 string code; // 存储该符号对应的编码 int leftChild, rightChild, parent; // 左、右孩子,父结点 }; 2.思路: (1)统计输入的字符串中不同字... 阅读详情
#ifndef CHUFFMANTREE_H_
#define CHUFFMANTREE_H_
#include <assert.h>
#include <iostream>
#include <string>
#include <deque>
using namespace std;
/***************************************************************************/
/*先谈谈霍夫曼编码的基本思想:
/*对于一个给定的概率数组,所有元素之和为1,为了便于算法实现,我们扩大100倍
/*选出序列中最小的两个元素,删除原序列中的这两个数,相加得到一个新的元素
/*再把新得到的数放入序列中,重复上述过程,直到序列中只有一个元素(100)
/*规定:1、左孩子必须不大于右孩子节点的值;2、左边编码为0,右边为1
/***************************************************************************/
typedef struct _ITEM
{
	int index;//元素在原来的数组中的索引值
	int data;//数据
}ITEM,*PITEM;
typedef struct _TREE
{
	_TREE* lChild;//指向左孩子
	_TREE* rChild;//指向右孩子
	_TREE* pParent;//指向父节点
	ITEM item;//当前节点的数据域
}TREE,*PTREE;
class CHuffmanTree
{
public:
	CHuffmanTree(int s[],const int len);
	virtual~ CHuffmanTree();
	//初始化树
	void InitTree()const;
	//打印输入的数据
	void ShowBuffer()const;
	//打印树
	void ShowTree()const;
	void ShowHuffmanCode();
protected:
	//对队列元素进行两次冒泡排序,以便选出最小的两个数
	void SortDeque();
	//选出队列中最小的两个元素构造新的树节点
	void Select(int& m,int& n);
	//构造哈弗曼树
	void CreateHuffmanTree();
private:
	int* pBuffer;//把元素复制到自己的内存里,指向首地址
	int m_iLength;//数组元素个数
	PTREE pTree;
	deque<ITEM> que;//双向队列,在这里面进行筛选最小的两个
};
#endif;
#include "stdafx.h"
#include "HuffmanTree.h"
CHuffmanTree::CHuffmanTree(int s[], const int len)
:pBuffer(NULL)
,pTree(NULL)
,m_iLength(0)
{
	assert(len>0);
	pBuffer=new int[len];
	int* p=pBuffer;
	for(int i=0;i<len;++i)
	{
		ITEM it;
		it.index=i;
		it.data=s[i];
		que.push_back(it);
		*(p+i)=s[i];
	}
	m_iLength=len;
	pTree=new TREE[2*len-1];
	InitTree();
}
CHuffmanTree::~CHuffmanTree()
{//回收内存
	if(pTree)
	{
		delete[] pTree;
		pTree=NULL;
	}
	if(pBuffer)
	{
		delete[] pBuffer;
		pBuffer=NULL;
	}
}
void CHuffmanTree::InitTree() const
{
	int* p=pBuffer;
	int i=0;
	for(;i<2*m_iLength-1;++i)
	{
		(pTree+i)->lChild=NULL;
		(pTree+i)->rChild=NULL;
		(pTree+i)->pParent=NULL;
		(pTree+i)->item.index=i;
	}
	for(i=0;i<m_iLength;++i)
		(pTree+i)->item.data=*(p+i);
	for(;i<2*m_iLength-1;++i)
		(pTree+i)->item.data=0;
}
void CHuffmanTree::ShowBuffer() const
{
	for(int i=0;i<m_iLength;++i)
		cout<<*(pBuffer+i)<<"   ";
	cout<<endl;
}
void CHuffmanTree::ShowTree() const
{
	cout<<"index         lChild        rChild        pParent       data"<<endl;
	for(int i=0;i<2*m_iLength-1;++i)
	{
		cout<<(pTree+i)->item.index<<"              ";
		if((pTree+i)->lChild)
			cout<<(pTree+i)->lChild->item.data<<"             ";
		else
			cout<<"0             ";
		if((pTree+i)->rChild)
			cout<<(pTree+i)->rChild->item.data<<"             ";
		else
			cout<<"0             ";
		if((pTree+i)->pParent)
			cout<<(pTree+i)->pParent->item.data<<"             ";
		else
			cout<<"0             ";  
		cout<<(pTree+i)->item.data<<endl;
	}
		
}
void CHuffmanTree::Select(int& m,int& n)
{
	if(que.size()<2)
		return;
	SortDeque();
	//经过两次冒泡排序,最小的两个元素的索引当然是0和1了
	m=que.at(0).index;
	n=que.at(1).index;
	//出队列
	que.pop_front();
	que.pop_front();
}
void CHuffmanTree::SortDeque()
{
	if(que.empty())
		return;
	//两次冒泡排序就可以筛选出最小的两个了
	for(int i=0;i<2;++i)
	{
		for(int j=que.size()-1;j>i;--j)
		{
			if(que.at(j).data<que.at(j-1).data)
			{
				ITEM temp=que.at(j);
				que.at(j)=que.at(j-1);
				que.at(j-1)=temp;
			}
		}
	}
}
void CHuffmanTree::CreateHuffmanTree()
{
	for(int i=m_iLength;i<2*m_iLength-1;++i)
	{
		int m=0,n=0;
		Select(m,n);
		(pTree+m)->pParent=(pTree+i);
		(pTree+n)->pParent=(pTree+i);
		(pTree+i)->lChild=(pTree+m);
		(pTree+i)->rChild=(pTree+n);
		(pTree+i)->item.index=i;
		(pTree+i)->item.data=(pTree+m)->item.data+(pTree+n)->item.data;
		que.push_back((pTree+i)->item);//关键!产生的新节点一定要放入队列中
	}
}
void CHuffmanTree::ShowHuffmanCode()
{
	CreateHuffmanTree();//生成霍夫曼树
	for(int i=0;i<m_iLength;++i)
	{
		TREE* p=(pTree+i);
		string s="";
		while(p->pParent)
		{//我们约定左0,右1
			if(p->pParent->lChild->item.index==p->item.index)
				s+="0";
			else
				s+="1";
			p=p->pParent;
		}
		s=string(s.rbegin(),s.rend());//逆置
		cout<<(pTree+i)->item.data<<"的编码为:"<<s<<endl;//打印每个元素的霍夫曼编码
	}
}

代码有注释,在此不再啰嗦.

测试:

#include "stdafx.h"
#include <iostream>
#include "huffmantree.h"
using std::cout;
using std::endl;

int _tmain(int argc, _TCHAR* argv[])
{
	int s[]={5,29,7,8,14,23,3,11};
	CHuffmanTree tree(s,8);
	tree.ShowBuffer();
	tree.ShowTree();
	tree.ShowHuffmanCode();
	tree.ShowTree();
	return 0;
}



 

 

 


 

霍夫曼编码c++实现 一、霍夫曼编码的原理:     在数据通信时,可以用0,1码的不同排列来表示字符。例如给定一段报文CAST CAST SAT AT A TASA,在报文中出现的字符集合是{C,A,S,T},各个字符出现的频度是{2,7,4,5}。若给每个字符一个等长的二进制表示,例如 C:00 A:01 S:10 T:11,则所发的报文将是00011011 00011011 100111 0111 01 1101 阅读详情

相关推荐

霍夫曼树实现8位256色灰度图像压缩与复原(C++)

霍夫曼树实现8位256色灰度图像的压缩与复原 网上很代码都是压缩和复原一个文件,即压缩后原地复原;然后在优快云上看过一份霍夫曼编码的图像压缩,我觉得写的有些复杂,只给了代码,也没有任何注释和main函数;于是我干脆自己写一份,压缩率是92.6%,如果是24位的bmp可以试试用霍夫曼树分块压缩。 一、实验语言与环境 Windows C++ Visual Studio Code或code::blo...

ggy67627336的博客 2395

C++哈夫曼树+哈夫曼编码的实现(双完整版)

C++版全网最全、详解、引导思考的哈夫曼树和哈夫曼编码讲解,剖析了关键代码,适合收藏~

不负AC不负卿的博客 2万+

C++实现霍夫曼编码

#include <iostream> #include <string> #include <cstdlib> #include <vector> #include <algorithm> using namespace std; class HNode { public: int weight; string con...

Rein的博客 2380

【数据结构C/C++】C语言哈夫曼编码与解码实现细则(附代码以及详细实现解释)

哈夫曼树作为最常见的考研树题目,拥有强大的压缩功能。 这篇文章将带你了解哈夫曼树如何实现编码与解码

Zhangsama1的博客 2万+

C++手搓JPEG压缩:从原理到实现的图像编码实战

图像压缩是计算机图形学和多媒体处理领域的核心技术,其核心原理在于通过算法减少图像数据的冗余信息,从而在保证视觉质量的前提下显著降低存储和传输成本。JPEG作为最广泛使用的有损图像压缩标准,其技术价值在于巧妙地结合了人眼视觉特性与信号处理理论。它通过色彩空间转换、离散余弦变换(DCT)、量化和熵编码等一系列步骤,将空间域的像素信息转换并压缩。在工程实践中,实现JPEG编码器需要深入处理位操作、内存管理和性能优化等底层问题。例如,离散余弦变换(DCT)将图像块从空间域转换到频率域,而量化步骤则是有选择地丢弃高频

weixin_33600816的博客 276

C++实现四大无损压缩算法详解——霍夫曼、算术编码、自适应霍夫曼与LZW字典编码

无损压缩算法在保持数据完整性的同时,通过消除统计冗余实现存储空间的有效节约。其核心原理基于信息论中的香农熵,利用符号出现频率的不均匀性进行变长编码,典型代表包括霍夫曼编码、算术编码、LZW等。该技术广泛应用于ZIP/RAR归档、PNG图像、GIF动画、HTTP内容压缩(如gzip)等场景,确保数据在压缩-解压循环后完全还原。与有损压缩不同,无损方法不允许任何信息丢失,适用于文本、代码、配置文件等对精度敏感的数据类型。

weixin_42573757的博客 1451

基于c++的哈夫曼编码

创建树主要过程,源码能运行( ̄︶ ̄)↗ 

qq_60948116的博客 5136

北邮数据结构课实战:C++霍夫曼编码树完整实现(含可执行文件与跨平台构建支持)

一套开箱即用的霍夫曼编码树C++实现,专为高校数据结构课程设计,支持字符频率输入、自动生成最优编码表、编码压缩与解码还原全流程。代码采用标准C++11编写,不依赖第三方库,通过CMake统一管理构建过程,已预编译Windows可执行文件HuffmanTree.exe,同时提供Makefile和CLion项目配置(.idea/.iml),适配Linux/macOS/Windows多平台本地编译。目录包含核心源码main.cpp、huffman子模块、详细README.md使用说明、.gitignore版本控制

echo99的专栏 171

哈夫曼树与哈夫曼编码(c++实现)

哈夫曼树与哈夫曼编码一、字符的机内表示二、 哈夫曼树的概念三、 哈夫曼树的理论实现四、 哈夫曼树的代码实现理论设计代码实现代码总结和测试 一、字符的机内表示 在计算机中每个西文字符是用一个编码表示,大多数编码系统都采用等长编码,如ASCII编码 例如在某段文本中用到了下列字符,括号中是它们出现的频率:a(10), e(15), i(12), s(3), t(4), 空格(13), 换行(1)。如采用定长编码,7个不同的字符至少要用3位编码。 下图给出了一种编码对应方法: 上述编码形式可以对应下面的二叉树,

H.A.N.的博客 7538

Camera 基础知识

Raw Sensor输出的Data格式为Raw,图像的效果处理使用BB端的ISP,BB端接收Raw data后进行一系列的图像处理(OB,Shading,AWB,Gamma,EE,ANR等),效果方面由BB端控制,需要针对不同的模组进行效果调试,Raw sensor是目前的主流,数据量比YUV Sensor小(RAW10 格式的sensor 1个pixel 10个bit)使用平台ISP处理,能支持较大的size。不过,相位对焦并不是那么完美,它对光线的要求就比较高,在弱光拍摄环境下,相位对焦就无能威力了。

手机-手表蓝牙开发工程师的博客 3062

Vector CANape的使用记录

开门见山,今天想和大家分享下CANape使用记录,分享原因是近日在分析一个客户现场软件问题时,需要用到CANape来实时的监测ECU中的变量,因为之前对CANape的认知比较浅薄,觉得标定工程师使用他就足够了,但是这次的经历让我觉得需要写点东西来记录自己学习并使用他的过程。 相信大家能够在网上找到很多关于如何使用CANape的文章,从新建Project到后面的数据的观测、保存以及回放等等。我个人也是这么学过来的,所以我不打算从那些方面着手去描述如何使用她,而是根据我的真实使用过程以及问题的抛出到如何解决来

2万+

C++实现霍夫曼编码:从原理到无损压缩实战

数据压缩是计算机科学中优化存储与传输效率的核心技术,其基本原理在于通过特定算法减少数据的冗余表示。在众多无损压缩算法中,霍夫曼编码以其基于信息熵的变长前缀编码原理脱颖而出,它通过统计符号频率构建最优二叉树,为高频符号分配短码、低频符号分配长码,从而在整体上降低数据编码长度。这项技术的工程价值在于平衡了压缩率与编解码复杂度,是理解熵编码和数据结构(如优先队列、二叉树)的经典实践。在应用场景上,霍夫曼编码不仅是ZIP、GZIP等通用压缩工具的基础模块,也广泛应用于JPEG图像编码、音视频编解码器等多媒体处理领域

weixin_34314962的博客 335

海康H304NAS 刷机飞牛

本文旨在分享如何将闲置的海康威视H304 NAS刷入飞牛NAS系统,并利用iStoreOS作为安装媒介。之前因为使用极空间NAS,这台H304闲置已久。最近尝试了飞牛NAS,在虚拟机上安装后挂载极空间的电影资源,体验不错,于是决定重新折腾这台H304。我个人喜欢尝试新系统,之前经常更新H304的固件,但设备总在使用一两年后出现故障,需要联系技术清理日志才能恢复。最后一次设备“变砖”后,连技术人员也联系不上了,自己尝试修复未果,设备就此闲置两三年。

u012985257的博客 2744

C++实现四大无损压缩算法:霍夫曼、算术、自适应与LZW编码详解

数据压缩是计算机科学中处理海量信息存储与传输的核心技术,其基本原理是通过消除数据中的冗余,在保证信息完整性的前提下减少其占用的空间。从信息论的角度看,无损压缩旨在逼近数据的熵极限,这通常通过统计编码或字典编码两大技术路线实现。在工程实践中,霍夫曼编码因其基于频率的贪心策略和简单高效的特点,成为入门首选;而算术编码则通过将整个消息映射为区间分数,理论上能达到更高的压缩率。这些算法的价值在于能直接嵌入到游戏、音视频处理、网络传输及嵌入式系统等对资源敏感的场景中,有效节省存储与带宽。本文聚焦于使用C++语言,从原

weixin_33928137的博客 406

实战教程:如何用Python+小波变换+CNN搞定医学影像中的条纹噪声(附完整代码)

本文提供了一套完整的实战方案,指导如何利用Python结合小波变换与卷积神经网络(CNN)去除医学影像中的条纹噪声。该方法通过小波变换精准定位噪声,再使用轻量化CNN进行针对性清除,有效保护图像细节,并附有可运行的完整代码,为医学影像处理与AI分析提供高效工具。

weixin_29056101的博客 268

Cadence HDL原理图库避坑指南:从Excel导入引脚到解决‘V- V+’报错(附FPGA实例)

本文详细介绍了Cadence HDL原理图库的高效构建与排错方法,重点讲解如何从Excel智能导入引脚数据并优化FPGA封装设计。通过数据预处理、智能导入和深度排错三个关键阶段,帮助工程师避免常见错误如‘V- V+’报错,提升设计效率和准确性。

weixin_28739079的博客 234

5分钟搞懂霍夫曼编码:从原理到C++实现(附完整代码)

本文深入解析了霍夫曼编码的原理,这是一种基于贪心策略的最优前缀码无损压缩算法。文章通过手工演练详细说明了如何根据字符频率构建霍夫曼树,并提供了使用现代C++(包括智能指针和STL容器)的完整实现代码,涵盖建树、编码、解码及性能分析,帮助读者从理论到实践全面掌握该经典算法。

app77的博客 406

少儿学编程系列--使用递归画出龙形曲线DragonCurve

龙形曲线(Dragon Curve) 龙形曲线(Dragon Curve)又叫分形龙,是一种自相似碎形曲线的统称,因形似龙的蜿蜒盘曲而得名 使用黄金比例画龙形曲线 根据黄金比例画一条龙曲线。每次递归,第一步向左转32.89度,移动0.74倍原距离;第二个递归步骤向右转46.99度,移动原来距离的0.55倍。请查看这个网页(https://larryriddle.agnesscott.org/ifs/heighway/goldenDragon.htm)了解关于龙形黄线数学的细节 龙形曲线效果 .

penriver的博客 2296

Algorithm第四版算法 C++实现(二十九)——霍夫曼(Huffman)压缩(文件压缩机制)

霍夫曼压缩真的式一个非常经典又非常优雅的算法。不知道大家是否都会求霍夫曼树。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。如果清楚的话,建议先去看一下霍夫曼树。他的原理是,将数据从小到大排序,将最小的两个生成一棵树,其权为二者的和。然后将其加入到队列中与其他的比较并继续此过程。 然后我们可以根据生成的树来获取前缀码。 然后用这些代码代替原本的数据。 class huffman { private: const static int r = 256; int freq[256] = {};

Charlesix59的博客 672

GEE:连续变化检测 CCD 第一步(导出ee.Algorithms.TemporalSegmentation.Ccdc函数的结果)

连续变化检测与分类(Continuous Change Detection and Classification, CCDC)主要有两个组件,一个连续变化检测 CCD,另外一个分类。在 Google Earth Engine (GEE)平台上进行 CCD 时间序列变化检测的时候,为了防止内存超限问题,将代码分为2阶段执行。第一阶段是运行 `ee.Algorithms.TemporalSegmentation.Ccdc` 函数,本文将详细介绍 CCD 的第一阶段的代码。

养乐多的博客 2492

简要介绍 | 雷达穿墙成像及其应用场景

本文简要介绍了雷达穿墙成像技术的原理、研究现状、挑战与未来展望,希望能为相关领域的研究与应用提供参考。具有广泛的应用前景。本文将详细介绍雷达穿墙成像的原理,以及其在不同应用场景中的实践。逆时偏移算法(Reverse-Time Migration, RTM)雷达穿墙成像技术是一种先进的遥感技术,具有。的能力,可用于探测室内目标。安全与救援、建筑结构检测等领域。雷达穿墙成像技术的核心原理是。是Green函数,表示从接收点。雷达穿墙成像及其应用场景。雷达穿墙成像及其应用场景。目标识别与定位准确性。

NLOS的博客 2232

C++高频知识点(二十二)

假设有一个简单的客户端和服务器程序,客户端每次向服务器发送一条消息,而服务器接收消息后回显给客户端。

Atticus的博客 803

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

[C++]数据结构:使用最小堆创建霍夫曼编码树HuffmanTree的过程

二话不多说,首先我们先来看个霍夫曼编码树的栗子。 假设我们想要压缩的是这个字符串: “beep boop beer!” 首先统计它们的出现次数,得到下面这张表: 然后根据出现的频率依次排序,放在一个优先队列Priority Queue中: 接下来的任务就是把这个Priority Queue转换成二叉树。 我们始终从Priority Queue的head取两个

汪海的实验室 7812

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

贪心算法

贪心算法-霍夫曼编码 霍夫曼编码是一种无损数据压缩算法。在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。例如,在英文中,e的出现机率最高,而z的出现概率则最低。当利...

weixin_34356310的博客 288

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: c++中char*\wchar_t*\string\wstring之间的相互转换
下一篇: C++读取歌词文件(LRC),分解时间和歌词的方法
疯狂-的-蜗牛
博客等级 码龄16年 427粉丝 104原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值