C++ 实现哈夫曼树和哈夫曼编码

  • 一.哈夫曼树的定义
  • 二.哈夫曼树的构造算法
  • 三.哈夫曼编码
  • 四.哈夫曼算法实现
    • 1.定义一个结点类
    • 2.定义一个哈夫曼编码类
    • 3.定义一个哈夫曼树类
    • 4.设置初始值
    • 5.构造哈夫曼树
    • 6.根据哈夫曼树求哈夫曼编码
    • 7.输出哈夫曼编码
    • 8.main函数

一.哈夫曼树的定义

  将树中的结点赋予一个有某种意义的数值,称此数值为该结点的权。从树根结点到该结点之间的路径长度与该结点上权的乘积称为结点的带权路径长度。树中所有叶子结点的带权路径长度之和称为该树的带权路径长度,通常记为:
WPL=∑i=1n0wiliWPL =\sum_{i=1}^{n_0}{w_il_i} \quad WPL=i=1∑n0​​wi​li​
其中,n0表示叶子结点的数目,wili(1≤i≤n0)分别表示叶子结点ki的权值和根ki之间的路径长度(即从叶子结点到达根结点的分支数)。
  在由n0个带权叶子结点构成的所有二叉树中,带权路径长度WPL最小的二叉树称为哈夫曼树(或最优二叉树)。

二.哈夫曼树的构造算法

哈夫曼算法:

  1. 根据给定的n0个权值W=(w1,w2,…wn0),对应结点构成n0棵二叉树的森林T=(T1,T2,…Tn0),其中,每棵二叉树Ti(1≤i≤n0)中都只有一个带权值wi的根结点,其左、右子树均为空。
  2. 在森林T中选取两棵结点的权值最小的子树分别作为左、右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左、右子树上根的权值之和。
  3. 在森林T中,用新得到的二叉树代替这两棵树。
  4. 重复2和3,直到T只含一棵树为止,这棵树便是哈夫曼树

定理:
  对于具有n0个叶子结点的哈夫曼树,共有2n0-1个结点。

三.哈夫曼编码

  设需要编码的字符集合为{d1,d2,…,dn0},各字符在电文中出现的次数集合为{w1,w2,…,wn0},以d1,d2,…,dn0作为叶子结点,以w1,w2,…,wn0作为各根结点到每个叶子结点的权值构造一棵哈夫曼树,规定哈夫曼树中的左分支为0,右分支为1,则从根结点到每个叶子结点所经过的分支对应的由0和1组成的序列便成为该结点对应字符的编码,称为哈夫曼编码。

四.哈夫曼算法实现

1.定义一个结点类

#include <iostream>
#include <stack>
#define MAX 100
#define MAXWEI 1000
using namespace std;class Node{public:char data;    //结点值double weight; //权值int parent; //双亲结点int lChild;   //左孩子结点int rChild; //右孩子结点
};

2.定义一个哈夫曼编码类

class HCode{public:stack<char> cd; //存放当前结点的哈夫曼编码
};

3.定义一个哈夫曼树类

class Huffman{public:void setValue(char*,double[],int);//设置初始值void createHuff();//构造哈夫曼树void createCode();//根据哈夫曼树求哈夫曼编码void dispHCoude();//输出哈夫曼编码private:int n;//权值和叶子结点的个数Node ht[MAX];//存放哈夫曼树HCode hcd[MAX]; //存放哈夫曼编码
};

4.设置初始值

void Huffman::setValue(char *str,double d[],int m){//str表示结点,d表示权值,两者一一对应,m表示个数n = m;for(int i=0;i<m;i++){Node* n = new Node();n->data = str[i];n->weight = d[i];ht[i] = *n;//将设置好值的结点存入ht数组中}
}

5.构造哈夫曼树

void Huffman::createHuff(){int i,k,lNode,rNode;double min1,min2;for(i=0;i<(2*n-1);i++){//为所有结点的相关域置初值-1ht[i].parent = -1;ht[i].lChild = -1;ht[i].rChild = -1;}for(i=n;i<(2*n-1);i++){//构造哈夫曼树,仅求非叶子结点min1=min2=MAXWEI;//初始时设置最大权值lNode=rNode=-1;//lNode,rNode为权值最小的结点位置for(k=0;k<=(i-1);k++){//循环条件根据外层循环改变而改变,是在ht数组中寻找权值最小的两个结点if(ht[k].parent==-1){if(ht[k].weight<min1){min2 = min1;rNode = lNode;min1 = ht[k].weight;lNode = k;}else if(ht[k].weight<min2){min2 = ht[k].weight;rNode = k;}}}ht[lNode].parent = i;ht[rNode].parent = i;ht[i].weight = ht[lNode].weight + ht[rNode].weight;ht[i].lChild = lNode;ht[i].rChild = rNode;}
}

6.根据哈夫曼树求哈夫曼编码

void Huffman::createCode(){//从叶子结点向树根结点编码int i,f,c;for(i=0;i<n;i++){//只遍历叶子结点c = i;f = ht[i].parent;hcd[i].cd.push('#');//将栈底置为‘#’,方便输出while(f!=-1){//循环到达树根结点if(ht[f].lChild == c){//当前结点是双亲结点的左孩子结点hcd[i].cd.push('0');}else{//是双亲结点的右孩子结点hcd[i].cd.push('1');}c = f;//再对双亲结点进行同样的操作f = ht[f].parent;} }}

7.输出哈夫曼编码

void Huffman::dispHCoude(){for(int i=0;i<n;i++){int j=0;cout << ht[i].data << "结点的编码为:" ;while(hcd[i].cd.top()!='#'){//编码全部输出完的条件char c = hcd[i].cd.top();cout << c;hcd[i].cd.pop();}cout << endl;   }
}

8.main函数

int main(){char a[] = {'a','b','c','d','e','f','g','h'};double d[] = {0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.1};Huffman h;h.setValue(a,d,8); h.createHuff();h.createCode();h.dispHCoude();return 0;
}

C++ 实现哈夫曼树和哈夫曼编码相关推荐

  1. 蓝桥哈夫曼树C语言,实验四 哈夫曼树及哈夫曼编码

    实验目的## 掌握哈夫曼树的概念.哈夫曼编码及其应用. 掌握生成哈夫曼树的算法. 会用哈夫曼树对传输报文进行编码. 掌握二叉树的二叉链表存储方式及相应操作的实现. ##实验内容## 用哈夫曼编码进行通 ...

  2. python哈夫曼树_python霍夫曼树

    class Node(): data=0 left=None right=None father=None def __init__(self,data,left,right): self.data= ...

  3. 一文看懂哈夫曼树与哈夫曼编码

    转自:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299884.html 在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUF ...

  4. 树:哈夫曼树和哈夫曼编码的详细介绍以及代码实现

    闲扯前言 哈夫曼编码的代码实现对于初学数据结构的同学可能会有些困难,没有必要灰心,其实没啥,学习就犹如攀登一座又一座的山峰,每当我们攻克一个难点后,回首来看,也不过如此嘛.我们要做的就是不断的去攀越学 ...

  5. 听说你还不懂哈夫曼树和哈夫曼编码

    基本概念 哈夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,在实际中有广泛的用途. 基本概念 路径:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径. 路径长度:路径上的分 ...

  6. 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  7. 【Java数据结构与算法】第十二章 哈夫曼树和哈夫曼编码

    第十二章 哈夫曼树和哈夫曼编码 文章目录 第十二章 哈夫曼树和哈夫曼编码 一.哈夫曼树 1.基本术语 2.构建思路 3.代码实现 三.哈夫曼编码 1.引入 2.介绍 3.代码实现哈夫曼编码综合案例 一 ...

  8. 【数据结构】树与树的表示、二叉树存储结构及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树与哈夫曼编码、集合及其运算

    1.树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基本操作之一:查找(根据某个给定关键字K,从集合R ...

  9. 【数据结构】-哈夫曼树以及哈夫曼编码

    哈夫曼树的几个定义 哈夫曼树又叫最优二叉树:特点是带权路径最短 带权路径长度:该结点到根结点的路径长度乘以该结点的权值. 树的带权路径长度(WPL):所有叶子结点到根结点的带全路径长度之和. 最优二叉 ...

最新文章

  1. powerdesigner箭头如何画_用Scratch编程画几何图形:如何画多边形
  2. 如何用计算机打出love,游戏中名字的LOVE怎么用符号打出来?
  3. LeetCode Algorithm 202. 快乐数
  4. OpenJudge NOI 1.7 34:回文子串
  5. FD.io的使用场景(VPP)
  6. 系统之美——系统思考与认识系统
  7. qt通过http连接mysql_Azure Database for MySQL 连接安全-(3) Private Endpoint
  8. 可计算行与计算复杂性多带图灵机实例
  9. vscode c++ 开发环境搭建(离线、内网)
  10. java技术管理的简历_基于javaweb个人简历生成及管理系统.doc
  11. 【CPRI】(2)组网方式及接口指标
  12. MDM数据分析设计方案
  13. HoloLens2之路-混合现实技术概述
  14. Grafana-创建仪表板的Best实践
  15. matlab如何寻找兼职
  16. 地网导通测试仪_江西地网接地导通测试仪特点
  17. python给矩阵赋值_python – 基本Numpy数组值赋值
  18. 从安装到连接,教你如何连上Mysql数据库
  19. 线性代数笔记21——伴随矩阵和克莱姆法则
  20. 2020-08-25

热门文章

  1. 网吧服务器软件维护合同范本,网吧电脑维护合同范本
  2. 微信小程序渲染图片报错:[渲染层网络层错误] Failed to load local image resource
  3. 突发事件检测: kleinberg 状态机模型
  4. 消费者太穷不愿买手机?苹果的份额创新高,撕下国产手机遮羞布
  5. Ubuntu 18.04 无法自动检测耳机解决方法
  6. IVR业务基础知识和制作技巧(转)
  7. python 容联云测试短信接口
  8. Unity GoogleVR Cardboard 开发
  9. 转载 锁机制与原子操作 第四篇
  10. Beta冲刺总结随笔