//编码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<fstream>
#include<map>
using namespace std; typedef struct HuffmanNode{
int w;//节点的权值
int ld, rd;//左右孩子节点
int p;//父节点
char ch;//当前节点的字符
HuffmanNode(){
ld = rd = p = -;
}
}huffmanNode, *pHuffmanNode; typedef pair<int, int> pii;//haffuman节点和它的编号 bool operator > (pii x, pii y){
return x.first > y.first;
} struct Huffman{
int cntNode;//总结点的个数
string orgCode;
string huffmanCode;
pHuffmanNode huffman = NULL;
priority_queue<pii, vector<pii>, greater<pii> >qNode;
map<string, char> huffmanMapx;//哈夫曼编码对应字符
map<char, string> huffmanMapy;//字符对应哈夫曼编码
void initHuffman(char *str){
orgCode = str;
cntNode = ;
int cnt[];//统计每一个节点的个数
memset(cnt, , sizeof(cnt));
for(int i=; str[i]; ++i){
if(cnt[str[i]]==) ++cntNode;
++cnt[str[i]];
}
huffman = new HuffmanNode[*(cntNode)];
int index = ;
for(int i=; i<; ++i){
if(cnt[i]!=){
huffman[index].w = cnt[i];
huffman[index].ch = i;
qNode.push(make_pair(huffman[index].w, index));
++index;
}
}
while(qNode.size()>=) {
pii ldPii = qNode.top();
qNode.pop();
pii rdPii = qNode.top();
qNode.pop();
huffman[index].w = ldPii.first + rdPii.first;
huffman[index].ld = ldPii.second;
huffman[index].rd = rdPii.second;
huffman[ldPii.second].p = index;
huffman[rdPii.second].p = index;
qNode.push(make_pair(huffman[index].w, index));
++index;
}
} void huffmanCoding() {
for(int i=; i<cntNode; ++i){//从每一个孩子节点向上寻找
string code = "";
for(int child=i, p=huffman[child].p; ~p; child = p, p = huffman[child].p) {
if(huffman[p].ld == child){//左子树
code += '';
} else if(huffman[p].rd == child){//右子树
code += '';
}
}
reverse(code.begin(), code.end());
huffmanMapx.insert(make_pair(code, huffman[i].ch));
huffmanMapy.insert(make_pair(huffman[i].ch, code));
}
} void outHuffmanTree(fstream &fout, int f){
if(huffman[f].ld==- && huffman[f].rd==-){
fout<<<<" ";
return ;
} else {
fout<<<<" ";
outHuffmanTree(fout, huffman[f].ld);
outHuffmanTree(fout, huffman[f].rd);
}
} void outHuffmanCode(){
huffmanCode = "";//存储字符串的哈夫曼编码之后的内容
fstream fout("out.txt", ios_base::out);
for(int i=; i<orgCode.length(); ++i){
huffmanCode += huffmanMapy[orgCode[i]];
}
cout<<huffmanCode<<endl;
fout<<huffmanCode<<endl;//想文件中输入huffman编码
int f = *cntNode-;//huffman树的父节点
outHuffmanTree(fout, f);
fout<<endl;
for(map<string, char>::iterator it = huffmanMapx.begin(); it!=huffmanMapx.end(); ++it){
cout<<it->first << " -> " << it->second<<endl;
fout<<it->first<<" "<<it->second<<endl; //向文件中输入HuffmanMap
}
}
}; int main(){
char str[];
Huffman huffman;
gets(str);
huffman.initHuffman(str);
huffman.huffmanCoding();
huffman.outHuffmanCode();
return ;
}
//译码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<fstream>
#include<map>
using namespace std; typedef struct HuffmanTreeNode{
HuffmanTreeNode *ld, *rd;
HuffmanTreeNode(){
ld = NULL;
rd = NULL;
}
} *pHuffmanTreeNode; struct Huffman{
pHuffmanTreeNode T;
string code;
map<string, char>huffmanMapx; void buildT(fstream &fin, pHuffmanTreeNode &T){
int w;
fin>>w;
T = new HuffmanTreeNode();
if(w==)
return ;
buildT(fin, T->ld);
buildT(fin, T->rd);
} void outT(pHuffmanTreeNode T){
if(T->ld != NULL){
cout<<<<endl;
outT(T->ld);
}
else return;
if(T->rd != NULL){
cout<<<<endl;
outT(T->rd);
}
} void initHuffmanTree(){
fstream fin("in.txt", ios_base::in);
T = NULL;
fin>>code;
buildT(fin, T);
//outT(T);
string mapContent;
while(getline(fin, mapContent)){
int index = mapContent.find_first_of(' ');
huffmanMapx.insert(make_pair(mapContent.substr(, index), mapContent[index+]));
}
} void outHuffmanEncode(){
string encode = "", cd="";
initHuffmanTree();
pHuffmanTreeNode p = T;
for(int i=; i<code.length(); ++i){
if(p->ld==NULL && p->rd==NULL){
encode+=huffmanMapx[cd];
cd="";
--i;
p=T;
} else {
cd+=code[i];
if(code[i]=='')
p=p->ld;
else if(code[i]=='')
p=p->rd;
}
if(i==code.length()-) encode+=huffmanMapx[cd];
}
cout<<encode<<endl;
}
}; int main(){
Huffman huffman;
huffman.outHuffmanEncode();
return ;
}

操作流程:

文本内容:aaaaaaabbbbbccdddd, and I am a student, my name is hjzgg!

1.首先利用''编码"工具将文本编码,会输出一个out.txt的文本,将out.txt文本中的内容发送给你的好友。

2.接受到out.txt文本的内容后,将内容复制到文本名为in.txt的文件中,利用"译码"工具(保证in.txt和译码工具在同一目录下)可以查看文本内容。

3.其中out.txt文本的格式如下:

Huffman树进行编码和译码的更多相关文章

  1. Huffman树的编码译码

    上个学期做的课程设计,关于Huffman树的编码译码. 要求: 输入Huffman树各个叶结点的字符和权值,建立Huffman树并执行编码操作 输入一行仅由01组成的电文字符串,根据建立的Huffma ...

  2. Huffman树与编码

    带权路径最小的二叉树称为最优二叉树或Huffman(哈夫曼树). Huffman树的构造 将节点的权值存入数组中,由数组开始构造Huffman树.初始化指针数组,指针指向含有权值的孤立节点. b = ...

  3. Huffman树与编码的简单实现

    好久没写代码了,这个是一个朋友问的要C实现,由于不会C,就用JAVA写了个简单的.注释掉的代码属性按照原来朋友发的题里带的参数,发现没什么用就给注释掉了. package other; import ...

  4. Huffman树及其编码(STL array实现)

    这篇随笔主要是Huffman编码,构建哈夫曼树有各种各样的实现方法,如优先队列,数组构成的树等,但本质都是堆. 这里我用数组来存储数据,以堆的思想来构建一个哈弗曼树,并存入vector中,进而实现哈夫 ...

  5. Huffman树及其编解码

    Huffman树--编解码 介绍:   Huffman树可以根据输入的字符串中某个字符出现的次数来给某个字符设定一个权值,然后可以根据权值的大小给一个给定的字符串编码,或者对一串编码进行解码,可以用于 ...

  6. 构造数列Huffman树总耗费_蓝桥杯

    快排! /** 问题描述 Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, …, pn-1},用这列数构造Huffman树的 ...

  7. Java蓝桥杯练习题——Huffman树

    Huffman树在编码中有着广泛的应用.在这里,我们只关心Huffman树的构造过程. 给出一列数{pi}={p0, p1, -, pn-1},用这列数构造Huffman树的过程如下: 找到{pi}中 ...

  8. Huffman树的构造及编码与译码的实现

    哈夫曼树介绍 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数) ...

  9. C++哈夫曼树编码和译码的实现

    一.背景介绍: 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的 ...

随机推荐

  1. mac下xampp的mysql无法自动启动

    mac下xampp的mysql无法自动启动,每次启动都要手动在终端里执行 sudo /Applications/XAMPP/xamppfiles/bin/mysql.server start 自动启动 ...

  2. MySQL多表查询

    第一种: select a.a1,a.a2,a.a3,b.b2,c.c2,d.d2 from a,b,c,d where a.a1=b.b1 and b.b1=c.c1 and c.c1=d.d1 第 ...

  3. Xpath基础语法学习

    背景: 之所以学习Xpath,是因为在学习selenium定位页面元素,总是定位不到元素.为了更好的开展自动化测试,先学习下Xpath. 一:Xpath是什么. 1:Xpath是一门在XML文档中查找 ...

  4. STM32之DMA+ADC

    借用小甲鱼的经典:各位互联网的广大网友们.大家早上中午晚上好..(打下小广告,因为小甲鱼的视频真的很不错).每次看小甲鱼的视频自学都是比较轻松愉快的..我在想,如果小甲鱼出STM32的视频,我会一集不 ...

  5. DSY3163*Eden的新背包问题

    Description "寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听."失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的 ...

  6. MySQL修改root密码的多种方法

    不知道在cmd模式下是不是区分大小写,我大写成功了,小写没成功,不知是我拼写的错误,还是区分大小写!!?? 方法1: 用SET PASSWORD命令 mysql -u root mysql> S ...

  7. 搬-Android - Wi-Fi Tutorial[转]

    http://www.tutorialspoint.com/android/android_wi_fi.htm Android allows applications to access to vie ...

  8. myeclipse tomcat内存溢出解决方法

    Tomcat直接启动正常,通过myeclipse启动tomcat内存溢出.MyEclipse启动Tomcat无视catalina.bat中设置内存大小的问题.在 tomcat的catalina.bat ...

  9. Spket在Eclipse下的安装和配置(图文教程)

    一.Spket简介 Spket是一个RIA的开发工具,具有代码自动完成.语法高亮.内容概要等功能,可以帮助开发人员高效的编写JavaScript程序. 效果图: 二.安装Spket 1.去官网(htt ...

  10. c#多线程介绍(上)

    转载原文:这里是链接内容 转载原文:这里写链接内容 转载原文:这里写链接内容 (重要事情说三遍) 引言 本文主要从线程的基础用法,CLR线程池当中工作者线程与I/O线程的开发,并行操作PLINQ等多个 ...