对哈夫曼编码的输出 c语言,哈夫曼编码问题
哈夫曼编码问题
代码由bug求改进
#include
#include
#include
using namespace std;
#define Max 200 //最大结点数目
#define INT 10000
char ch[Max]; //叶子结点信息(字符)
int i,w[Max]; //w为输入的权值数组
typedef struct{
unsigned int weight; //权值
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树
typedef char * *HuffmanCode; //动态分配数组存储哈夫曼编码表
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)
{//w存放n个字符的权值(均>0),构造哈夫曼树HT,并求出n个字符的哈夫曼编码HC。
int s1,s2,j,min1,min2;
if(n<=1) return;
int m=2*n-1;
HT=new HTNode[m+1];//0号单元未用
for(i=1;i<=n;++i) //哈夫曼树叶子结点的初始化
{
HT[i].weight=w[i]; 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;
}
for(i=n+1;i<=m;++i) //建哈夫曼树
{ //在HT[1..i-1]选择parent为0且weight最小的两个结点S1和S2
min1=min2=INT;
for(j=1;j
if(HT[j].parent==0&&(HT[j].weight
{
min1=HT[j].weight;
s1=j;
}
for(j=1;j
if(HT[j].parent==0&&(HT[j].weight
{ min2=HT[j].weight;
s2=j;
}
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;
ch[i]='?';//非叶子结点的结点字符
}
//从叶子到根逆向求每个字符的哈夫曼编码
HC=new char*[n+1]; //分配n个字符编码的头指针向量
char *cd=new char[n]; //分配求编码的工作空间
HT[i].lchild=s1; HT[i].rchild=s2;
cd[n-1]='\0'; //编码结束符
for(i=1;i<=n;i++) //逐个字符求哈夫曼编码
{
int c,f,start=n-1;//编码结束符位置
for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
/*cd[--start]=(HT[f].lchild==c?'0':'1';*/ //从叶子到根逆向求编码
if(HT[f].lchild==c)
cd[--start]='0';
else
cd[--start]='1';
HC[i]=new char[n-start];//为第i个字符编码分配空间
strcpy(HC[i],&cd[start]); //从cd复制编码(串)到HC
}
delete cd;
}
void Initialization(HuffmanTree &HT,HuffmanCode &HC,int &n)//初始化,注意加引用符号
{
char c;
ifstream fin("hfmTree.txt",ios::in);//读出
if(fin.fail()) //若不存在此文件,则从终端读入
{
cout<
cin>>n;
cout<
for(i=1;i<=n;i++)
{
//getchar()是在输入缓冲区顺序读入一个字符(包括空格、回车和tab)。
getchar(); //取消换行符
//getchar每次只能读取一个字符.如果需要取消'\n'的影响,可以用getchar();来清除,
//这里getchar();只是取得了'\n'但是并没有赋给任何字符变量,所以不会有影响,相当于清除了这个字符.
ch[i]=getchar(); //保证空格读进
cin>>w[i];
}
HuffmanCoding(HT,HC,w,n);
ofstream fout("hfmTree.txt",ios::out);//写入
cout<
for(i=1;i<=2*n-1;i++)//写入字符,权值,父结点,左右孩子
fout<
for(i=1;i<=n;i++)//写入字符及相应的编码
fout<
fout.close();
}
else{ //如果文件存在,即读到内存中
fin>>n;
for(i=1;i<=2*n-1;i++)
{
fin.get(ch[i]);
fin>>HT[i].weight>>HT[i].parent>>HT[i].lchild>>HT[i].rchild;
fin.get(c);
}
for(i=1;i<=n;i++)
{
fin.get(ch[i]);
fin>>HC[i];
fin.get(c);
}
}
fin.close();
}
void Encoding(HuffmanCode & HC,int n) //编码
{
int i,j;
string str,str1;
ifstream fin("ToBeTran.txt",ios::in);//打开文件
ofstream fout("CodeFile.txt",ios::out);
if(fin.fail())
cout<
getline(fin,str);//读入一行,可以读入空格
while(!fin.eof())//文件不结束
{
getline(fin,str1);
str=str+str1;
}
fin.close();
for(i=0;str[i]!='\0';i++)//编码过程,一个字符一个字符来
{
j=1;
while(ch[j]!=str[i]&&j<=n) j++;
if(j<=n) fout<
}
fout<
fout.close();
}
void Decoding(HuffmanTree HT,int n)//译码
{
int j,len,m;
string str;
m=2*n-1;
ifstream fin("CodeFile.txt",ios::in);
ofstream fout("TextFile.txt",ios::out);
if(fin.fail())
{
cout<
return ;
}
fin>>str;
fin.close();
len=str.size();
i=0;j=m;
while(i
{ //从根出发,按字符'0'或'1'确定找左孩子或右孩子,直至叶子结点
if(str[i]=='0')
j=HT[j].lchild;
else j=HT[j].rchild;
if(HT[j].lchild==0)
{ fout<
i++;
}
fout<
}
void Print(HuffmanTree HT,int n)//打印代码文件
{
int i;
char str[Max];
ifstream fin("CodeFile.txt",ios::in);
ofstream fout("CodePrin.txt",ios::out);
if(fin.fail())
cout<
fin>>str;
cout<
for(i=0;i
{
if(i%50==0&&i!=0) //毎50以换行
{
cout<
}
cout<
}
cout<
fin.close(); fout.close();
}
//非叶子结点用权值表示,叶子结点用字符表示
void PrintTree(HuffmanTree &HT,int &n)
{
ofstream fout("TreePrint.txt",ios::out);//写入文件
int l,j,m=0,k=1,q=0,p=0,r=1;//k 表示层数,r表示每层的结点数
for(i=1;i<=2*n-1;i++)
if(HT[i].parent==0)//找根结点的权值
m=HT[i].weight;
for(l=m;l>0;l--)
for(i=1;i<=2*n-1;i++)
if(HT[i].weight==l)
{
for(j=0;j
{ cout<
if(ch[i]!='?') //如果是叶子结点就直接输出,否则输出权重
{
if(ch[i]==' ') ch[i]='#';//标记为空的字符
{ cout<
}
else
{ cout<
q++;//q 记录每层的结点数目
if(q==r) { k++; r=2*p; p=0; q=0; } //如果该层的结点满了,就到下一层,即k+1
}
}
int main()
{
HuffmanTree HT;
HuffmanCode HC;
char c;
int n;
HT=new HTNode[Max];
HC=new char*[Max];
for(int i=1;i<=Max;i++)//初始化
HC[i]=new char[20];
cout<
cout<
cout<
cout<
cout<
cout<
cout<
cout<
cout<
while(c!='Q')
{
cout<
cin>>c;
switch(c)
{
case '1': Initialization(HT,HC,n);
cout<
break;
case '2': Encoding(HC,n);
cout<
break;
case '3': Decoding(HT,n);
cout<
break;
case '4': Print(HT,n);
cout<
break;
case '5': cout<
PrintTree(HT,n);
cout<
default: break;
}
}
return 0;
}
对哈夫曼编码的输出 c语言,哈夫曼编码问题相关推荐
- 电文的编码和译码c语言实现,电文的编码及译码.doc
数据结构课程设计 题目:电文的编码与译码 院系: 班级: 学号: 姓名: 2014-2015年度 第1学期 目录 一.题目:电文的编码与译码3 二.设计目标3 三.问题描述3 四.需求分析3 五.概要 ...
- huffman编码译码器用c语言,基于哈弗曼编码的数据压缩C语言实现
haod 摘要 数据压缩技术是一项重要实用的信息技术.信息时代的到来,信息量迅速增长,使得数据压缩也显得越来越重要.数据压缩有多种编码方法,大致可分为无损压缩编码和有损压缩编码.其中,Huffman ...
- C语言简单好玩编码,TZC1464:C语言实验题——简单编码
描述: 将一串文本译成密码,密码的规律是:将原来的小写字母全部翻译成大写字母,大写字母全部翻译成小写字母,数字的翻译规律如下: 0-->9 1-->8 2-->7 3-->6 ...
- 树12——构造哈夫曼树并输出哈夫曼编码
树12--哈夫曼树 哈夫曼树 为一组权值分别为2.4.7.15的结点序列构造一棵哈夫曼树,然后输出相应的哈夫曼编码. 为了便于设计,可利用一个二维数组实现哈夫曼树的算法.因为需要保存字符的权重.双亲结 ...
- 电文的编码和译码,哈夫曼编码译码(C语言)
内容: 从键盘接收一串电文字符,输出对应的Huffman(哈夫曼)编码,同时,能翻译由Huffman编码生成的代码串,输出对应的电文字符串.设计要求: (1)构造一棵Huffman树: ...
- 哈夫曼树(Huffman Tree),与哈夫曼编码
目录 一.哈夫曼树 1.什么是哈夫曼树? 2.哈夫曼树关键字说明 3.用代码实现哈夫曼树思路分析 4.代码实现 二.哈夫曼编码 1.哈夫曼编码基本介绍 2.原理剖析 3.代码实现 一.哈夫曼树 1.什 ...
- c语言赫夫曼树的编码与译码,哈夫曼树与编码译码实现
一.哈弗曼树的基本概念. 哈夫曼树,又称最优树,是一类带权路径长度最短的树.下面有几个概念: (1)路径. 树中一个结点到另一个结点之间的分支构成这两个结点之间的路径. (2)路径长度. 路径上的分枝 ...
- 信息论霍夫曼编码c语言,Huffman 信息论与编码 - 下载 - 搜珍网
霍夫曼编码/Shiyan4/Shiyan.sln 霍夫曼编码/Shiyan4/Shiyan.suo 霍夫曼编码/Shiyan4/Shiyan.v11.suo 霍夫曼编码/Shiyan4/Shiyan4 ...
- C语言哈夫曼编码压缩解压
C语言哈夫曼编码压缩解压 一.实验目的 掌握哈夫曼编码基本运算以及存储结构表示. 二.实验内容: 1.系统要求包含以下功能 1)初始化:从终端读入字符集大小n,以及n个字符和n个权值(或者读入字符集和 ...
最新文章
- 资源 | 25个深度学习开源数据集,have fun !
- python导出csv不带引号的句子_python csv writer在不需要时添加引号
- 【 C 】队列的链式存储实现
- 基于libUSB的USB设备固件更新程序(下载数据)(转)
- python echo和linux交互_Python与shell的3种交互方式介绍
- 作业 给计算机编号 winform
- 离开小米后 周受资将加入字节跳动担任CFO
- 风控人必知必会的征信知识
- 拼装html字符串的最快方法
- Python 入门指南 官网文档
- 超简单的Matlab附加功能安装包的安装方法
- 用VBA自动整理系统导出的订单
- 最全NISP二级习题汇总
- 小饼叮当 最爱铜锣烧
- 读书笔记:自动控制原理
- 三十四个超级经典小故事
- mysql左表有右表没有_查询左表存在而右表不存在的记录
- 上标和下标复制大全(含0~9、字母、特殊字符)
- linux安装xbox无线手柄,想不到xbox手柄配对方法居然还有3个【详解】
- 余承东吐槽iPhone X长的丑体验差;雷军称小米明年要进世界500强;特斯拉股价被指太荒唐丨价值早报
热门文章
- 昆仑通态Mcgspro学习笔记(V3.3.6)
- ===(js表示恒等于及类型相同和值都相同)
- 一个人从MyIe到FireFox的转变
- unity3d 理解刚体(Rigidbody)和碰撞体(Collider)以及触发器(Is Trigger),边学边更新
- 深度学习中的归一化方法简介(BN、LN、IN、GN)
- 被骗到香港做传销!(当事人详细回忆)
- 如何通过python获取股票数据接口l2?
- 软件工程过程和软件系统分析与设计
- win8.1系统如何激活
- 第六、七章 嵌入式Linux开发