理论基础 —— 二叉树 —— 哈夫曼树与哈夫曼编码
【哈夫曼树】
1.相关概念
1)叶结点的权值:对叶结点赋予的一个有意义的数值量
2)二叉树的带权路径长度(WPL):设二叉树具有 n 个带权叶结点,从根结点到各叶结点的路径长度与相应叶节点权值的乘积之和
即:,其中 Wk 为第 k 个叶结点的权值,Lk 为从根结点到第 k 个叶结点的路径长度
如图所示,WPL=2*2+3*2+4*2+7*2=4+6+8+14=32
3)哈夫曼树:给定一组具有确定权值的叶结点,可以构造出不同的二叉树,其中 WPL 最小的二叉树称为哈夫曼树。
2.哈夫曼树特点
1)权值越小,离根越远;权值越大,离根越近。
2)只有度为 0 的叶结点和度为 2 的分支结点,不存在度为 1 的结点
3.哈夫曼算法
1)初始化:由给定的 n 个权值构造 n 棵只有一个根节点的二叉树,得到一个二叉树集合 F
2)选取与合并:从二叉树集合 F 中选取根节点权值最小的两棵二叉树分别作为左右子树构造一棵新的二叉树,这棵新二叉树的根节点的权值为其左、右子树根结点的权值和
3)删除与加入:从 F 中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入到 F 中
4)重复 2)、3) 步,当集合中只剩下一棵二叉树时,这棵二叉树就是哈夫曼树
4.计算WPL
给出 n 个叶结点的权值,计算构成哈夫曼树的 WPL
int main() {int n;cin>>n;priority_queue<int,vector<int>,greater<int> > huffman;for(int i=1;i<=n;i++){int x;cin>>x;huffman.push(x);}int res=0;for(int i=1;i<n;i++){int x=huffman.top();huffman.pop();int y=huffman.top();huffman.pop();int temp=x+y;res+=temp;huffman.push(temp);}cout<<res<<endl;return 0;
}
【哈夫曼编码】
1.编码
在进行程序设计时,通常给每一个字符标记一个单独的代码来表示一组字符,即编码。
在进行二进制编码时,假设所有的代码都等长,那么表示 n 个不同的字符需要 位,这称为等长编码。
如果每个字符的使用频率相等,那么等长编码无疑是空间效率最高的编码方法,而如果字符出现的频率不同,则可以让频率高的字符采用尽可能短的编码,频率低的字符采用尽可能长的编码,来构造出一种不等长编码,从而获得更好的空间效率。
在设计不等长编码时,要考虑解码的唯一性,如果一组编码中任一编码都不是其他任何一个编码的前缀,那么称这组编码为前缀编码,其保证了编码被解码时的唯一性。
2.哈夫曼编码
哈夫曼树可用于构造最短的前缀编码方案,即哈夫曼编码,具体做法如下:
1)设需要编码的字符集为:,他们在字符串中出现的频率为:
2)以 作为叶结点, 作为叶结点的权值,构造一棵哈夫曼树
3)规定哈夫曼编码树的左分支代表 0,右分支代表 1,则从根结点到每个叶结点所经过的路径组成的 0、1 序列即为该叶结点对应字符的编码
3.实现
struct Node{int weight;Node *lchild,*rchild;
};
typedef Node *tree;
tree create(int arr[],int n){tree forest[N];tree root=NULL;for (int i=0; i<n; i++){//将所有点存入森林tree temp;temp=(tree)malloc(sizeof(Node));temp->weight = arr[i];temp->lchild = temp->rchild = NULL;forest[i]=temp;}for(int i=1; i<n; i++) {//n-1次循环建哈夫曼树int minn=-1,minnSub;//minn为最小值树根下标,minnsub为次小值树根下标for(int j=0; j<n; j++) {if (forest[j]!=NULL && minn==-1) {minn=j;continue;}if (forest[j]!=NULL) {minnSub=j;break;}}for (int j=minnSub; j<n; j++){//根据minn与minnSub赋值if(forest[j]!=NULL){if(forest[j]->weight < forest[minn]->weight){minnSub=minn;minn=j;}else if(forest[j]->weight < forest[minnSub]->weight){minnSub=j;}}}//建新树root = (tree)malloc(sizeof(Node));root->weight = forest[minn]->weight + forest[minnSub]->weight;root->lchild = forest[minn];root->rchild = forest[minnSub];forest[minn]=root;//指向新树的指针赋给minn位置forest[minnSub]=NULL;//minnSub位置为空}return root;
}
int getWPL(tree &root,int len){//计算哈夫曼树带权路径长度WPLif(root==NULL)return 0;else {if(root->lchild==NULL&&root->rchild==NULL)//叶节点return root->weight*len;elsereturn getWPL(root->lchild,len+1)+getWPL(root->rchild,len+1);}
}
void HuffmanCoding(tree &root,int len,int arr[]){//哈夫曼树编码if(root!=NULL){if(root->lchild==NULL&&root->rchild==NULL){printf("结点为%d的字符的编码为: ",root->weight);for(int i=0;i<len;i++)printf("%d", arr[i]);printf("\n");}else{arr[len]=0;HuffmanCoding(root->lchild,len+1,arr);arr[len]=1;HuffmanCoding(root->rchild,len+1,arr);}}
}
int main(){int n=6;//长度int arr[]={3,9,5,12,6,15};//权值tree root=create(arr,n);int WPL=getWPL(root,0);printf("WPL=%d\n",WPL);printf("==========各节点的哈夫曼树编码==========\n");HuffmanCoding(root,0,arr);return 0;
}
理论基础 —— 二叉树 —— 哈夫曼树与哈夫曼编码相关推荐
- 【数据结构】树与树的表示、二叉树存储结构及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树与哈夫曼编码、集合及其运算
1.树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基本操作之一:查找(根据某个给定关键字K,从集合R ...
- 蓝桥哈夫曼树C语言,实验四 哈夫曼树及哈夫曼编码
实验目的## 掌握哈夫曼树的概念.哈夫曼编码及其应用. 掌握生成哈夫曼树的算法. 会用哈夫曼树对传输报文进行编码. 掌握二叉树的二叉链表存储方式及相应操作的实现. ##实验内容## 用哈夫曼编码进行通 ...
- 一文看懂哈夫曼树与哈夫曼编码
转自:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299884.html 在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUF ...
- 树:哈夫曼树和哈夫曼编码的详细介绍以及代码实现
闲扯前言 哈夫曼编码的代码实现对于初学数据结构的同学可能会有些困难,没有必要灰心,其实没啥,学习就犹如攀登一座又一座的山峰,每当我们攻克一个难点后,回首来看,也不过如此嘛.我们要做的就是不断的去攀越学 ...
- 听说你还不懂哈夫曼树和哈夫曼编码
基本概念 哈夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,在实际中有广泛的用途. 基本概念 路径:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径. 路径长度:路径上的分 ...
- 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- 【Java数据结构与算法】第十二章 哈夫曼树和哈夫曼编码
第十二章 哈夫曼树和哈夫曼编码 文章目录 第十二章 哈夫曼树和哈夫曼编码 一.哈夫曼树 1.基本术语 2.构建思路 3.代码实现 三.哈夫曼编码 1.引入 2.介绍 3.代码实现哈夫曼编码综合案例 一 ...
- 【数据结构】-哈夫曼树以及哈夫曼编码
哈夫曼树的几个定义 哈夫曼树又叫最优二叉树:特点是带权路径最短 带权路径长度:该结点到根结点的路径长度乘以该结点的权值. 树的带权路径长度(WPL):所有叶子结点到根结点的带全路径长度之和. 最优二叉 ...
- C++ 实现哈夫曼树和哈夫曼编码
C++ 实现哈夫曼树和哈夫曼编码 一.哈夫曼树的定义 二.哈夫曼树的构造算法 三.哈夫曼编码 四.哈夫曼算法实现 1.定义一个结点类 2.定义一个哈夫曼编码类 3.定义一个哈夫曼树类 4.设置初始值 ...
- 霍夫曼树(赫夫曼树、哈夫曼树)
霍夫曼树:给定n个权值做为n个叶子节点,若该树的带权路径长度达到最小,这棵树为最优二叉树,也称赫夫曼树. 霍夫曼树中的几个概念 路径和路径长度 一棵树中,一个节点往下可以达到的孩子或孙子节点之间的通路 ...
最新文章
- 【廖雪峰python入门笔记】set
- js实现当前导航菜单高亮显示
- hive数据仓库摘录和总结
- HDU1029 - Ignatius and the Princess IV【水题】
- 次世代手游美术资源优化干货分享
- 【pyqt5学习】——graphicView显示opencv图像
- 枚举反射的应用(sql update语句匹配)
- 两轮差速驱动机器人运动模型及应用分析
- docker export/import到docker容器迁移的思考
- 简单的抽奖function
- Nginx - 限制并发、限制访问速率、限制流量
- 【STM32开发环境搭建】 - st-link驱动安装和串口驱动安装
- 普通话测试-短文60篇文章,附带拼音(21-30篇)
- matlab 图像处理之边缘提取
- 如果程序员能早知道这些该有多好!
- css里的英文翻译,css常见英文翻译
- 小白学SLAM的流水账(一):跑通ORB踩过的坑
- WPF实现仿Glitch闪烁特效
- Autodesk SketchBook手机版 v5.1.5安卓版
- 《O N E 影视厅》管理系统——WAMP架构win10+apache+mysql+php