哈夫曼编码问题

代码由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语言,哈夫曼编码问题相关推荐

  1. 电文的编码和译码c语言实现,电文的编码及译码.doc

    数据结构课程设计 题目:电文的编码与译码 院系: 班级: 学号: 姓名: 2014-2015年度 第1学期 目录 一.题目:电文的编码与译码3 二.设计目标3 三.问题描述3 四.需求分析3 五.概要 ...

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

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

  3. C语言简单好玩编码,TZC1464:C语言实验题——简单编码

    描述: 将一串文本译成密码,密码的规律是:将原来的小写字母全部翻译成大写字母,大写字母全部翻译成小写字母,数字的翻译规律如下: 0-->9 1-->8 2-->7 3-->6 ...

  4. 树12——构造哈夫曼树并输出哈夫曼编码

    树12--哈夫曼树 哈夫曼树 为一组权值分别为2.4.7.15的结点序列构造一棵哈夫曼树,然后输出相应的哈夫曼编码. 为了便于设计,可利用一个二维数组实现哈夫曼树的算法.因为需要保存字符的权重.双亲结 ...

  5. 电文的编码和译码,哈夫曼编码译码(C语言)

    内容: 从键盘接收一串电文字符,输出对应的Huffman(哈夫曼)编码,同时,能翻译由Huffman编码生成的代码串,输出对应的电文字符串.设计要求: (1)构造一棵Huffman树:         ...

  6. 哈夫曼树(Huffman Tree),与哈夫曼编码

    目录 一.哈夫曼树 1.什么是哈夫曼树? 2.哈夫曼树关键字说明 3.用代码实现哈夫曼树思路分析 4.代码实现 二.哈夫曼编码 1.哈夫曼编码基本介绍 2.原理剖析 3.代码实现 一.哈夫曼树 1.什 ...

  7. c语言赫夫曼树的编码与译码,哈夫曼树与编码译码实现

    一.哈弗曼树的基本概念. 哈夫曼树,又称最优树,是一类带权路径长度最短的树.下面有几个概念: (1)路径. 树中一个结点到另一个结点之间的分支构成这两个结点之间的路径. (2)路径长度. 路径上的分枝 ...

  8. 信息论霍夫曼编码c语言,Huffman 信息论与编码 - 下载 - 搜珍网

    霍夫曼编码/Shiyan4/Shiyan.sln 霍夫曼编码/Shiyan4/Shiyan.suo 霍夫曼编码/Shiyan4/Shiyan.v11.suo 霍夫曼编码/Shiyan4/Shiyan4 ...

  9. C语言哈夫曼编码压缩解压

    C语言哈夫曼编码压缩解压 一.实验目的 掌握哈夫曼编码基本运算以及存储结构表示. 二.实验内容: 1.系统要求包含以下功能 1)初始化:从终端读入字符集大小n,以及n个字符和n个权值(或者读入字符集和 ...

最新文章

  1. 资源 | 25个深度学习开源数据集,have fun !
  2. python导出csv不带引号的句子_python csv writer在不需要时添加引号
  3. 【 C 】队列的链式存储实现
  4. 基于libUSB的USB设备固件更新程序(下载数据)(转)
  5. python echo和linux交互_Python与shell的3种交互方式介绍
  6. 作业 给计算机编号 winform
  7. 离开小米后 周受资将加入字节跳动担任CFO
  8. 风控人必知必会的征信知识
  9. 拼装html字符串的最快方法
  10. Python 入门指南 官网文档
  11. 超简单的Matlab附加功能安装包的安装方法
  12. 用VBA自动整理系统导出的订单
  13. 最全NISP二级习题汇总
  14. 小饼叮当 最爱铜锣烧
  15. 读书笔记:自动控制原理
  16. 三十四个超级经典小故事
  17. mysql左表有右表没有_查询左表存在而右表不存在的记录
  18. 上标和下标复制大全(含0~9、字母、特殊字符)
  19. linux安装xbox无线手柄,想不到xbox手柄配对方法居然还有3个【详解】
  20. 余承东吐槽iPhone X长的丑体验差;雷军称小米明年要进世界500强;特斯拉股价被指太荒唐丨价值早报

热门文章

  1. 昆仑通态Mcgspro学习笔记(V3.3.6)
  2. ===(js表示恒等于及类型相同和值都相同)
  3. 一个人从MyIe到FireFox的转变
  4. unity3d 理解刚体(Rigidbody)和碰撞体(Collider)以及触发器(Is Trigger),边学边更新
  5. 深度学习中的归一化方法简介(BN、LN、IN、GN)
  6. 被骗到香港做传销!(当事人详细回忆)
  7. 如何通过python获取股票数据接口l2?
  8. 软件工程过程和软件系统分析与设计
  9. win8.1系统如何激活
  10. 第六、七章 嵌入式Linux开发