Huffman的应用_Huffman编码
//最优二叉树
#include <iostream>
#include <iomanip>
using namespace std; //定义结点类型
//【weight | lchid | rchild | parent】
//为了判定一个结点是否已加入到要建立的哈夫曼树中
//可通过parent域的值来确定.
//初始时parent = -1,当结点加入到树中时,该结点parent的值
//为其父亲结点在数组Huffman中的序号.
template<typename T>
struct HuffNode {
T weight; //权值
int parent; //指向父节点的指针域(结点元素的下标)
int lch; //左指针域
int rch; //右指针域
}; //哈夫曼树的构造算法
template<typename T>
HuffNode<T> *HuffmanTree(int n, const T& sign) //生成最优二叉树
{
const int MAX_VALUE = ;
int i, j, min1, min2, x1, x2; //min1为最小值, min2为次小值, x1位最小值下标, x2位次小值下标
HuffNode<T> *ht = new HuffNode<T>[ * n - ]; //一个含有n个叶子结点的最优二叉树,总共有2*n-1个结点
HuffNode<T> *huffNode = ht;
for (i = ; i < * n - ; i++) //最优二叉树结点数组初始化
{
huffNode[i].weight = ; //权值都设为0
huffNode[i].parent = -; //父节点,左右孩子结点
huffNode[i].lch = -;
huffNode[i].rch = -; //都设置为-1,-1代表空
}
for (i = ; i < n; i++) //依次输入n个叶子结点的权值
cin >> huffNode[i].weight; for (i = ; i < n - ; i++)
{
min1 = min2 = MAX_VALUE;
// x1, x2 用来保存找到的两个最小结点在数组中的位置
x1 = x2 = ;
for (j = ; j < n + i; j++) //因为外循环每循环一次,实际结点个数增加到n+i个
{
if (huffNode[j].weight < min1 && huffNode[j].parent == -)
{
min2 = min1; //存在权值小于min1, 则min1赋值给次小值
x2 = x1; //次小值下标改变
min1 = huffNode[j].weight; //当前权值赋值给最小值
x1 = j; //并保存最小值下标
}
else if (huffNode[j].weight < min2 && huffNode[j].parent == -)
{
min2 = huffNode[j].weight; //当前值赋值给次小值
x2 = j; //保存次小值下标
}
}
//将找出的两个子树合并成一颗子树
//对找到的两个最小结点的父指针域进行赋值
huffNode[x1].parent = n + i;
huffNode[x2].parent = n + i;
//新合成树位置上的权值
huffNode[n + i].weight = huffNode[x1].weight + huffNode[x2].weight;
//两个最小结点的父结点的左右孩子域进行操作
huffNode[n + i].lch = x1;
huffNode[n + i].rch = x2;
}
return ht;
} template<typename T>
void ShowHTree(HuffNode<T> *HT, int nodeNum)
{
HuffNode<T> *p = HT;
int k;
cout << "k" << "\t\t" << "Weight" << "\t\t" << "Parent"
<< "\t\t" << "Lchild" << "\t\t" << "Rchild" << endl;
for (k = ; k < * nodeNum - ; k++)
{
cout << k << "\t\t" << (p + k)->weight << "\t\t"
<< (p + k)->parent << "\t\t"
<< (p + k)->lch << "\t\t" << (p + k)->rch << endl;
}
} /*************************编码*******************************/ const int MAXBIT = ; //定义Huffman编码的最大长度 //对于第i个字符,它的Huffman编码存放在Huffman[i].bit中的 从 Huffman[i].start 到 n 的分量中
struct HCodeType {
int bit[MAXBIT]; //用来保存字符 的 Huffman编码
int start; //start表示该编码在bit中的开始位置
}; void HuffmanCode(int n)
{
const int MAXODE = , MAXLEAF = ; //最大编码长度,最多叶子数
HuffNode<int> *huffNode; //用于 生成Huffman 编码
HCodeType *huffCode, cd;
int i, j, c, par, sign = ; huffNode = HuffmanTree(n, sign); //建立Huffman树 huffCode = new HCodeType[n]; //初始化HuffCode
for (int k = ; k < n; k++)
huffCode[k].bit[i] = ; ShowHTree(huffNode, n); /**********************编码过程*************************/
for (i = ; i < n; i++) //n--是叶结点数,不是全部结点数
{
cd.start = n - ; //从叶结点开始
c = i; //c为 i的工作指针,以防误操作修改了 i
par = huffNode[c].parent;
while (par != -) //由叶结点向上直到树根
{
if (huffNode[par].lch == c) //右子树编号 == c ==> 右是0标志
cd.bit[cd.start] = ;
else //左是 1 标志
cd.bit[cd.start] = ;
cd.start--; //开始位置向前
c = par; //得到父亲结点的下标
par = huffNode[c].parent; //由叶结点向上直到树根 -- 得到父级点的父亲结点
}
for (j = cd.start + ; j < n; j++) //保存求出的每个叶结点的哈夫曼编码和编码的起始位
{
huffCode[i].bit[j] = cd.bit[j];
}
huffCode[i].start = cd.start; //设置编码的开始位置
} //输出
for (i = ; i < n; i++) //输出每个叶子结点的哈夫曼编码
{
for (j = huffCode[i].start + ; j < n; j++) {
cout << huffCode[i].bit[j] ;
}
cout << endl;
}
} int main()
{
int n; cout << "请输入叶子结点个数: " << endl;
cin >> n; HuffmanCode(n); system("pause"); return ;
}
Huffman的应用_Huffman编码的更多相关文章
- Huffman 哈夫曼编码与译码的原理剖析及C++实现
原理 我们在信息存储时,希望以最少的空间去存储最大的数据,方便数据的传输,那么该怎样做呢? 我们想到将源信息转化为01序列存储,但是这样以来又有一个问题,就是子串匹配问题,我们为了解决这个方法,想到了 ...
- huffman树即Huffma编码的实现
自己写的Huffman树生成与Huffman编码实现 (实现了核心功能 ,打出了每个字符的huffman编码 其他的懒得实现了,有兴趣的朋友可以自己在我的基础增加功能 ) /* 原创文章 转载请附上原 ...
- Huffman树的编码译码
上个学期做的课程设计,关于Huffman树的编码译码. 要求: 输入Huffman树各个叶结点的字符和权值,建立Huffman树并执行编码操作 输入一行仅由01组成的电文字符串,根据建立的Huffma ...
- Jcompress: 一款基于huffman编码和最小堆的压缩、解压缩小程序
前言 最近基于huffman编码和最小堆排序算法实现了一个压缩.解压缩的小程序.其源代码已经上传到github上面: Jcompress下载地址 .在本人的github上面有一个叫Utility的re ...
- Huffman树的构造及编码与译码的实现
哈夫曼树介绍 哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树.所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数) ...
- Huffman树及其编解码
Huffman树--编解码 介绍: Huffman树可以根据输入的字符串中某个字符出现的次数来给某个字符设定一个权值,然后可以根据权值的大小给一个给定的字符串编码,或者对一串编码进行解码,可以用于 ...
- bzoj 4198: [Noi2015]荷马史诗
Description 追逐影子的人,自己就是影子. --荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由& ...
- gzip 所使用压缩算法的基本原理(选摘)
摘自:http://blog.csdn.net/ghevinn/article/details/45747465 gzip 所使用压缩算法的基本原理 gzip 对于要压缩的文件,首先使用LZ77算法 ...
- javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题
赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...
随机推荐
- Spring.Net 简单入门学习
Spring.NET IoC容器的用法. 通过简单的例子学习Spring.Net 1.先创建一个控制台程序项目. 2.添加IUserInfoDal 接口. namespace Spring.Net { ...
- 线段树 HDU 3397(真)
5 种操作 0 1 然后 异或 似乎这种2个更新的先后每次都搞不清 覆盖有覆盖就可以不异或 也不知道为什么 #include<stdio.h> #include<string.h& ...
- jQuery插件 -- Cookie插件jquery.cookie.js(转)
Cookie是网站设计者放置在客户端的小文本文件.Cookie能为用户提供很多的使得,例如购物网站存储用户曾经浏览过的产品列表,或者门户网站记住用户喜欢选择浏览哪类新闻. 在用户允许的情况下,还可以存 ...
- Xcode使错误停在出错代码上
创建异常断点 依次选择“Debug”>“Breakpoints”>“Create Execption Breakpoint”
- BZOJ2818 Gcd
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- Gulp和Webpack工具的区别
引用知乎的回答:https://www.zhihu.com/question/37020798 怎么解释呢?因为 Gulp 和 browserify / webpack 不是一回事 Gulp应该和Gr ...
- 30秒懂SQL中的join(2幅图+30秒)
废话不多说,直接上图秒懂. t1表的结构与数据如下: t2表的结构与数据如下: inner join select * from t1 inner join t2 on t1.id = t2.id; ...
- C#------接口的理解
转载: http://blog.jobbole.com/85751/
- ARCGIS常用几种本地数据AE初始化
1.Personal GDB 新建一个在E盘的名为test的mdb: IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactoryCl ...
- java 获取文件列表,并按照文件名称排序
需求:获取全部的日志文件,并按照文件名称倒序排列,把最新的文件放在最前1.获取全部的日志文件:(方法:public List<String> ergodic(File file,List& ...