前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【C++实验】哈夫曼树与哈夫曼编码实验

【C++实验】哈夫曼树与哈夫曼编码实验

作者头像
哈__
发布于 2024-06-23 04:38:53
发布于 2024-06-23 04:38:53
22800
代码可运行
举报
文章被收录于专栏:哈哈熊哈哈熊
运行总次数:0
代码可运行

问题描述:

利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的u信息收发编写一个哈夫曼码的编/译码系统。

基本要求:

(1)接收原始数据(电文):从终端输入电文(电文为一个字符串,假设仅由26个小写英文字母构成)。 (2)编码:利用已建好的哈夫曼树,对电文进行编码。

(3)打印编码规则:即字符与编码的一一对应关系。

(4)打印显示电文以及该电文对应的哈夫曼编码。

(5)接收原始数据(哈夫曼编码):从终端输入一串哈二进制哈夫曼编码(由

0和1构成)。

(6)译码:利用已建好的哈夫曼树对该二进制编码进行译码。

(7)打印译码内容:将译码结果显示在终端上。

直接上代码,大家可以自己运行测试。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
using namespace std;
class HFMtreeNode
{
	public:
		HFMtreeNode()
		{
			this->lchild=-1;
			this->rchild=-1;
			this->parent=-1;
			this->weight=0;
		}
		int lchild;
		int rchild;
		int weight;
		int parent;
};
class HuffCode
{
	public:
		HuffCode(int size)
		{
			this->bit=new int[size];
			this->start=size-1;
		}
		int *bit;//长度至少容下26个小写英文字母 
		int start;
};
bool isNumStr(string str)
{
	int n=str.length();
	bool isNum_str =true;  
	for(int i=0;i<n;i++)
	{
		if(str[i]-'0'<0||str[i]-'0'>9)
		{
			isNum_str=false;
			break;
		}
	}
	return isNum_str;
}
void func()
{
	int Hash [26][2];//记录输入字符串中每个字符的权重, 
	int hash=0;
	int temp[26][2];//按权重不为0的顺序排列Hash中的字符 和字符位置 
	int number=0;//统计总共出现的字符 
	for(int i=0;i<26;i++)
	{
		for(int j=0;j<2;j++)
		{
			Hash[i][j]=0;
		}
	}
	cout<<"请输入要进行被构建的字符串:"; 
	string str,num_str;
	cin>>str;
	for(int i=0;i<str.length();i++)
	{
		if(Hash[str[i]-97][0]==0)
		{
			Hash[str[i]-97][1]=hash;
			hash++;
		}
		Hash[str[i]-97][0]+=1;
	}
	for(int i=0;i<26;i++)
	{
		if(Hash[i][0]!=0)
		{
			 cout<<char(i+97)<<"的权重为:"<<Hash[i][0]<<endl;
			 temp[number][0]=Hash[i][0];
			 temp[number][1]=i;
			 number++;
		} 
	}
	HFMtreeNode *hfm=new HFMtreeNode[2*number-1];
	HuffCode **code=new HuffCode*[number];//字符编码 
	for(int i=0;i<number;i++)
	{
		hfm[i].weight=temp[i][0];
		code[i]=new HuffCode(number);
	}
	//开始构建哈夫曼树 
	for(int i=0;i<number-1;i++)
	{
		int x1=0,x2=0,m1=1000,m2=1000;
		for(int j=0;j<number+i;j++)
		{
			if(hfm[j].parent==-1&&hfm[j].weight<m1)
			{
				m2=m1;
				x2=x1;
				m1=hfm[j].weight;
				x1=j;
			}
			else if(hfm[j].parent==-1&&hfm[j].weight<m2)
			{
				m2=hfm[j].weight;
				x2=j;
			}
		}
		hfm[x2].parent=number+i;
		hfm[x1].parent=number+i;
		hfm[number+i].lchild=x1;
		hfm[number+i].rchild=x2;
		hfm[number+i].weight=hfm[x1].weight+hfm[x2].weight;
	}
	//哈夫曼树构建完成 
	
	//开始构建编码
	int p,c;
	for(int i=0;i<number;i++)//有几个字符构建几个编码 
	{
		c=i;
		p=hfm[c].parent;
		while(p!=-1)
		{
			if(hfm[p].lchild==c) code[i]->bit[code[i]->start]=0;
			else code[i]->bit[code[i]->start]=1;
			code[i]->start--;
			c=p;
			p=hfm[c].parent;
		}
		code[i]->start++;
	} 
	//编码构建结束 
	cout<<"编码前的字符串:"<<str;
	cout<<endl<<"编码后:"<<endl;
	for(int i=0;i<number;i++)
	{
		cout<<char(temp[i][1]+97)<<":";
		for(int j=code[i]->start;j<number;j++)
		{
			cout<<code[i]->bit[j];
		}
		cout<<endl;
	}
	//打印编码 
	cout<<"原字符串经过转换后:";
	for(int i=0;i<str.length();i++)
	{
		int n=Hash[str[i]-97][1];
		int m=code[n]->start;
		for(int j=m;j<number;j++)
		{
			cout<<code[n]->bit[j];
		}
		cout<<" ";
	}
	
	//将数字编码通过树转回字母,通过对hfm的遍历,hfm[i]表示的字符和temp[i]表示的字符相同,可通过temp[i][1]+97,来表示这个字符 
	cout<<endl<<"----------------------------------------"<<endl;
	cout<<"请输入需要被转译的数字串:";
	cin>>num_str;
	int n=num_str.length();
	//开始对字符串进行转译 
	//首先判断字符串输入的是不是数字串 
	while(!isNumStr(num_str))
	{
		cout<<"您输入的不是数字编码,请从新输入:";
		cin>>num_str;
	}
	
	//对数字编码进行处理
	HFMtreeNode h=hfm[2*number-2];
	int pos=-1;//记录下标 
	string result="";
	for(int i=0;i<n;i++)
	{
			if(num_str[i]-'0'==0)
			{
				pos=h.lchild;
				if(pos==-1) 
				{
					result="错误!";
					break;
				}
				h=hfm[pos];
			}
			else if(num_str[i]-'0'==1)
			{	
				pos=h.rchild;
				if(pos==-1)
				{
					result="错误!";
					break;
				}
				h=hfm[pos];
			}
			else
			{
				result="错误!";
				break;
			}
		if(pos>=0&&pos<number) 
		{
			result+=char(temp[pos][1]+97);
			h=hfm[2*number-2];
			pos=-1;
		}
	} 
	if(h.parent!=-1) 
	{
		result="错误!";
	}
	cout<<"数字转译后的字符串为:";
	cout<<result;
}

int main()
{
	func();
	
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
哈夫曼编码
1.哈夫曼编码是一种可以被唯一解读的二进制编码 2.前缀编码保证了解码时不会有多种可能 3.哈夫曼编码有不等长和等长两种编码,为了保证不等长编码的唯一性,使用前缀编码 4.频率低的采用短编码,频率高的采用长编码。
大忽悠爱学习
2021/03/18
8050
【数据结构】【程序填空】赫夫曼编码
例如有一个叶子权值是29,后来生成一个中间结点权值也是29,那么叶子为左孩子,中间结点为右孩子
叶茂林
2023/07/30
1710
数据结构 哈夫曼编码/译码器
题目8:哈夫曼编码/译码器 实验类型(验证/设计/创新):设计 学时:16 课程设计内容: 设计一个哈夫曼编码/译码系统,对一个文本文件中的字符进行哈夫曼编码,生成编码文件;反过来,可将一个编码文件译码还原为一个文本文件(.txt)。要求: 7.输入一个待压缩的文本文件名, 统计文本文件中各字符的个数作为权值,生成哈夫曼树; 8.将文本文件利用哈夫曼树进行编码,生成压缩文件; 9.输入一个待解压的压缩文件名称,并利用相应的哈夫曼树将编码序列译码; 10.可显示指定的压缩文件和文本文件; 课程设计要求: 熟练掌握哈夫曼树的构建方法;能够运用哈夫曼树实现哈夫曼编码和译码。 重点难点: 【本课程设计重点】哈夫曼树的构建和哈夫曼编码。 【本课程设计难点】各字符出现频率的统计、哈夫曼树的构建和哈夫曼译码。
川川菜鸟
2021/10/18
7790
数据结构——哈夫曼树的实现以及编码(C语言实现)
      利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。构造哈夫曼树时,首先将由n个字
Gorit
2021/12/09
2.3K0
数据结构——哈夫曼树的实现以及编码(C语言实现)
【数据结构】建立二叉树以及哈夫曼树及哈夫曼编码
文章目录 5.4.1 方式 5.4.2 由先根和中根遍历序列建二叉树 5.4.3 由后根和中根遍历序列建二叉树 5.4.4 由标明空子树的先根遍历建立二叉树 5.4.5 由完全二叉树的顺序存储结构建立二叉链式存储结构 5.5 哈夫曼树及哈夫曼编码 5.5.1 基本概念 5.5.2 最优二叉树 5.5.3 构建哈夫曼树 5.5.4 哈夫曼编码 5.5.5 哈夫曼编码类 5.4.1 方式 四种方式可以建立二叉树 由先根和中根遍历序列建二叉树 由后根和中根遍历序列建二叉树 由标明空子树的先根遍
陶然同学
2023/02/26
1.1K0
【数据结构】建立二叉树以及哈夫曼树及哈夫曼编码
数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 数据结构图文解析之:树的简介及二叉排序树C++模板实现. 数据结构图文解析之:AVL树详解及C++模板实现 数据结构图文解析之:二叉堆详解及C++模板实现 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现 数据结构图文解析之:直接插入排序及其优化(二分插入排序)解析及C++实现 1. 哈夫曼编码简
Tencent JCoder
2018/07/02
1.1K0
哈夫曼树
代码 #include <iostream> #include <cstring> #include <queue> using namespace std; typedef struct node{ struct node* lchild; struct node* rchild; int weight; node(int w,struct node* l,struct node* r){ this->weight = w; this->lchild = l; this->rchil
AI那点小事
2020/04/20
4370
哈夫曼树
【数据结构】【程序填空】赫夫曼解码
例如有一个叶子权值是29,后来生成一个中间结点权值也是29,那么叶子为左孩子,中间结点为右孩子
叶茂林
2023/07/30
1990
漫画:“哈夫曼编码” 是什么鬼?
在上一期,我们介绍了一种特殊的数据结构 “哈夫曼树”,也被称为最优二叉树。没看过的小伙伴可以点击下方链接:
小灰
2020/04/22
89519
赫夫曼编译码器的源代码
用户11070251
2024/04/11
1180
数据结构之哈夫曼树和编码器的构造
在最近的自学数据结构的过程中,为加深树的理解,码了一个二叉树编码器,请多多指教: ---- #include #define MAXBIT100 //最大子树 #define MAXVALUE10000 //最大值 #define MAXLEAF30 //最大编码数 #define MAXNODEMAXLEAF*2 -1 //最大节点数 typedef struct { int bit[MAXBIT]; int start; } HCodeType;/*编码结构体*/ typedef struct { i
云时之间
2018/04/11
6700
c++ 哈夫曼树简便构造(数据结构作业篇)
    MinHeapNode(char data, unsigned freq)
星辉
2019/01/15
1.5K0
Huffman 编码的编程与实现 C语言
一 、目的: 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. 程序:
timerring
2025/05/24
1380
Huffman 编码的编程与实现 C语言
种树:二叉树、二叉搜索树、AVL树、红黑树、哈夫曼树、B树、树与森林
树是我们计算机中非常重要的一种数据结构,同时使用树这种数据结构,可以描述现实生活中的很多事物,例如家 谱、单位的组织架构、等等。 树是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就 是说它是根朝上,而叶朝下的。
看、未来
2020/08/25
1.2K0
种树:二叉树、二叉搜索树、AVL树、红黑树、哈夫曼树、B树、树与森林
[数据结构] 使用最小堆思想实现哈夫曼编解码
假设有n个权值,构造有n个叶子结点的二叉树,每个叶子结点的权值是n个权值之一,这样的二叉树可以构造很多棵,其中必有一棵是带权路径长度最小的,这棵二叉树就称为最优二叉树或哈夫曼树。
泰坦HW
2020/07/22
2.4K0
[数据结构] 使用最小堆思想实现哈夫曼编解码
哈夫曼树
哈夫曼树 1.相关概念 2.哈夫曼树的特点 为了让带权路径长度计算值最小 3,哈夫曼树的基本思想 4.哈夫曼树的构造过程 5.哈夫曼树的存储结构 6.伪代码 7.图示 8.代码 9.例子 #include<iostream> using namespace std; //哈夫曼树----静态链表方式存储 struct HtnNode { int weight;// 权值 int l
大忽悠爱学习
2022/05/05
4150
哈夫曼树
数据结构(15)–哈夫曼树以及哈夫曼编码的实现「建议收藏」
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说数据结构(15)--哈夫曼树以及哈夫曼编码的实现「建议收藏」,希望能够帮助大家进步!!!
Java架构师必看
2022/10/05
2.8K0
数据结构(15)–哈夫曼树以及哈夫曼编码的实现「建议收藏」
原以为哈夫曼树、哈夫曼编码很难,结果……
哈夫曼树、哈夫曼编码很多人可能听过,但是可能并没有认真学习了解,今天这篇就比较详细的讲一下哈夫曼树。
main方法
2021/07/19
6740
原以为哈夫曼树、哈夫曼编码很难,结果……
数据结构 Huffman树
Huffman 介绍 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点
Kindear
2017/12/29
1.5K0
数据结构 Huffman树
哈夫曼树
哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径
Java架构师必看
2021/12/27
7210
相关推荐
哈夫曼编码
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验