目录

哈夫曼树静态数组形式建立

哈夫曼树二叉链表形式建立

求WPL

哈夫曼树编码解码

更新


哈夫曼树的建立有两种方式,一种是通过静态数组的方式来建立(这种方式比较简洁明了好理解),由于不想篇幅太长了,我还是po出一篇大佬的优秀文章来解释建立哈夫曼树吧

哈夫曼树静态数组形式建立

哈夫曼树的基本概念及创建(c/c++)_gets_s的博客-CSDN博客一、一些基本概念1、路径:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径。2、路径长度:路径上的分支数目称作路径长度。3、树的路径长度:从树根到每一结点的路径长度之和。4、权:赋予某个实体的一个量,是对实体的某个或某些属性的数值化描述。5、结点的带权路径长度:从该结点到树根之间的路径长度与结点上权的乘积。6、树的带权路径长度:树中所有叶子结点的带权路径长度之和,通常记为:7、哈夫曼树:假设有m个权值{w1,w2,…,wm},可以构造一棵含n个叶子结点的二叉树,每个叶子结点的权为https://blog.csdn.net/gets_s/article/details/106160072?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91%E5%BB%BA%E7%AB%8B&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-106160072.nonecase&spm=1018.2226.3001.4187

哈夫曼树二叉链表形式建立

方法:

(1)由原始数据生成森林;

(2) 在森林中选取两棵根结点权值最小的和次小的二叉树作为左右子树构造一棵新的二叉树,其根结点的权值为左右子树根结点权值之和。规定左子树根结点的权值小于右子树根结点的权值。 (3)将新的二叉树加入到森林F中,去除原两棵权值最小的树;

(4)重复2、3步骤,直至F中只剩一棵树为止。 注意:参看书中P146的例子。

类定义(要用到最小堆)

#include "heap.h"
const  int DefaultSize = 20;   //缺省权值集合大小
template <class T, class E>
struct HuffmanNode {        //树结点的类定义E data;                //结点数据HuffmanNode<T, E> *parent;HuffmanNode<T, E> *leftChild, *rightChild;            //左、右子女和父结点指针HuffmanNode () : Parent(NULL), leftChild(NULL),rightChild(NULL) { }  //构造函数  HuffmanNode (E elem,                  //构造函数HuffmanNode<T, E> *pr = NULL, HuffmanNode<T, E> *left = NULL,     HuffmanNode<T, E> *right = NULL) : data (elem), parent (pr), leftChild (left),  rightChild (right) { }
};template <class T,  class E>
class HuffmanTree {     //Huffman树类定义
public:HuffmanTree (E w[], int n);  //构造函数~HuffmanTree() { delete Tree(root);}  //析构函数
protected:HuffmanNode<T, E> *root;         //树的根void deleteTree (HuffmanNode<T, E> *t);         //删除以 t 为根的子树void mergeTree (HuffmanNode<T, E>& ht1, HuffmanNode<T, E>& ht2,HuffmanNode<T, E> *& parent);
};

实现算法

template <class T, class E>
HuffmanTree<T, E>::HuffmanTree (E w[], int n) {
//给出 n 个权值w[1]~w[n], 构造Huffman树minHeap<T, E> hp;    //使用最小堆存放森林HuffmanNode<T, E> *parent, &first, &second; HuffmanNode<T, E> *NodeList =new HuffmanNode<T,E>[n];    //森林for (int i = 0; i < n; i++) {NodeList[i].data = w[i+1];NodeList[i].leftChild = NULL;         NodeList[i].rightChild = NULL;NodeList[i].parent = NULL;hp.Insert(NodeList[i]); //插入最小堆中}for (i = 0; i < n-1; i++) {  //n-1趟, 建Huffman树hp.Remove (first);         //根权值最小的树hp.Remove (second);    //根权值次小的树merge (first, second, parent); //合并hp.Insert (*parent);        //重新插入堆中root = parent;     //建立根结点}
};template <class T, class E>
void HuffmanTree<T, E>::
mergeTree (HuffmanNode<T, E>& bt1, HuffmanNode<T, E>& bt2, HuffmanNode<T, E> *& parent) {parent = new E;parent->leftChild = &bt1;parent->rightChild = &bt2;parent->data.key =bt1.root->data.key+bt2.root->data.key;bt1.root->parent = bt2.root->parent = parent;
};

求WPL

思路非常棒

int WPLrec(LBTree* lbt,int n)
{int wpl = 0;if (lbt != NULL){if (lbt->lchild == NULL && lbt->rchild == NULL)wpl += n * lbt->weigth;wpl += WPLrec(lbt->lchild, n + 1);wpl += WPLrec(lbt->rchild, n + 1);}return wpl;
}

递归算法好理解

下面的例子中深度要初始化为0;

二叉树的带权路径长度WPL算法实现_薛定谔的猫的博客-CSDN博客文章目录题目描述算法思想实现代码题目描述 二叉树的带权路径长度WPL是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树,采用二叉链表存储,叶子结点的weight域为该结点的权值。请设计一个算法,求二叉树的带权路径长度。算法思想可以使用先序遍历或层次遍历解决问题。<1>算法思想一:基于先序递归遍历。用一个static变量记录WPL,把每个结点的深度作为递归函数的一个参数传递。若该结点是叶结点,则变量WPL加上该结点的深度与权值之和。若该结点是非叶结点,则左子树不为空时,对左子https://blog.csdn.net/weixin_44162361/article/details/120851879?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163506287716780357222924%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163506287716780357222924&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~hot_rank-5-120851879.first_rank_v2_pc_rank_v29&utm_term=wpl%E7%AE%97%E6%B3%95&spm=1018.2226.3001.4187

哈夫曼树编码解码

编码:

里面的字母的权值代表字母出现的次数;

方法:

(1)用{ 2,4, 2,3, 3  }作为叶子结点的权值生成一棵哈夫曼树,并将对应权值wi的叶子结点注明对应的字符;

(2)约定左分支表示字符“0”,右分支表示字符‘1’

(3)从叶子结点开始,顺着双亲反推上去,直到根结点,路径上的‘0’或‘1’连接的序列就是结点对应的字符的二进制编码的逆序。

哈夫曼树的建立、编码以及WPL值的计算_SSPUmyl的博客-CSDN博客_哈夫曼树wpl假设用于通信的电文由字符集{A,B,C,D,E,F}中的字母构成,这些字母在电文中出现的概率分别为{0.10,0.19,0.20,0.35,0.12,0.04},要求: 1、构造一棵Huffman树,填写下表,要求左结点的权不大于右结点的权 2、在下表中填入各字符的Huffman编码(左分支为”0”,右分支为”1”) 3、求带权路径长度 解析: 1、哈夫曼树的构造 将电文概率由大到https://blog.csdn.net/SSPUmyl/article/details/53467604?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163505694316780357218848%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163505694316780357218848&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-53467604.first_rank_v2_pc_rank_v29&utm_term=wpl&spm=1018.2226.3001.4187数据结构(15)--哈夫曼树以及哈夫曼编码的实现_小白的专栏-CSDN博客_博夫曼


更新

太难顶了上面

我这边弄了个初始化Huffman树的简洁代码,没有那么多接口的

初始化

//w[]为每个字符的权重,c[]为每个字符的内容,n为字符的个数,静态实现struct huffmannode
{float weigth;//每个结点的权值char s;      //每个结点的数据int right, left, parent;int code[20];//哈夫曼编码int codesize;//每个节点的哈夫曼编码长度
};huffmanTree::huffmanTree(float w[], char c[], int n) {huffmannode *x;x = new huffmannode[100];    //长度自定int countcode = n;int elemsize = countcode * 2 - 1;for (int i = 0; i < elemsize; i++)    //初始化{x[i].s = c[i];x[i].weigth = w[i];x[i].left = x[i].right = x[i].parent = -1;}int minfirst, minsecond;int postag1, postag2;for (int i = 0; i < countcode - 1; i++) {minfirst = minsecond = 1000000;    //初始为最大postag1 = postag2 = 0;for (int j = 0; j < countcode + i; j++){if (x[j].weigth < minfirst && x[j].parent == -1){minsecond = minfirst;     //最小保存到次小postag2 = postag1;minfirst = x[j].weigth;postag1 = j;}else if (x[j].weigth < minsecond && x[j].parent == -1){minsecond = x[j].weigth;postag2 = j;}}x[postag1].parent = countcode + i;x[postag2].parent = countcode + i;x[countcode + i].weigth = x[postag1].weigth + x[postag2].weigth;x[countcode + i].left = postag1;x[countcode + i].right = postag2;x[countcode + i].parent = -1;}
}

编码

//countcode为字符个数,x为Huffman树,利用栈来实现编码解码
void huffmanTree::encode(int countcode,huffmanTree *x) {stack<int> s;int j, count;for (int i = 0; i < countcode; i++){j = i;while (x[j].parent != -1){if (x[x[j].parent].left== j) { s.push(0); }else if (x[x[j].parent].right == j) { s.push(1); }j = x[j].parent;}int temp = 0;while (!s.empty()){x[i].code[temp++] = s.top();s.pop();}x[i].codesize = temp;}cout << "编码成功!" << endl;
}

解码

//elemsize是静态数组哈夫曼树中开辟的空间,即:空间大小=节点个数*2-1
void huffmanTree::decode(int elemsize) {int w = elemsize - 1;char co;while (cin>>co) {co=in.get();        //读co的‘0’,‘1’字符if (co == '0') {w = x[w].left;}else if (co == '1') {w = x[w].right;}if (x[w].left == -1 && x[w].right == -1) {cout << x[w].s;w = elemsize - 1;}}cout << "译码成功!" << endl;
}

哈夫曼树建立与二叉树WPL算法以及相关例题相关推荐

  1. 哈夫曼树及求其WPL的算法

    哈夫曼树及求其WPL算法 一.概念 给定 N N N个权值作为 N N N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree ...

  2. 哈夫曼编码(基于哈夫曼树-最优二叉树,不唯一)、B树(b-树)、B+树

    整合自: http://blog.csdn.net/shuangde800/article/details/7341289 http://www.cnblogs.com/Jezze/archive/2 ...

  3. 赫夫曼树建立c语言源程序编译结果详细解释,哈夫曼树的建立与实现最终版(备份存档)...

    <哈夫曼树的建立与实现.doc>由会员分享,可免费在线阅读全文,更多与<哈夫曼树的建立与实现(最终版)>相关文档资源请在帮帮文库(www.woc88.com)数亿文档库存里搜索 ...

  4. HNU数据结构哈夫曼树建立

    根据下面给定的字母和权重建立Huffman编码树,并给出各个字母的代码. (A,2)(B,3)(C,5)(D,7)(E,11)(F,13)(G,17) (H,19)(I,23)(J,31)(K,37) ...

  5. 赫夫曼树及求解最小WPL的实现

    赫夫曼树 定义: 假设有m个权值{W1,W2,...Wm},可以构造一颗含有n个叶子节点的二叉树,每个叶子节点的权为Wj,则其中树的带权路径长度即WPL最小的二叉树称作最优二叉树或赫夫曼树. 算法思想 ...

  6. 数据结构与算法之Huffman tree(赫夫曼树 / 霍夫曼树 / 哈夫曼树 / 最优二叉树)

    目录 赫夫曼树概述 定义 构造赫夫曼树步骤 代码实现 赫夫曼树概述 HuffmanTree因为翻译不同所以有其他的名字:赫夫曼树.霍夫曼树.哈夫曼树 赫夫曼树又称最优二叉树,是一种带权路径长度最短的二 ...

  7. java 实现最优二叉树_哈夫曼树(最优二叉树) - Java实现

    简介 哈夫曼树(Huffman)树又称最优二叉树,是指对于一组带有确定权值的叶子结点所构造的具有带权路径长度最短的二叉树.从树中一个结点到另一个结点之间的分支构成了两结点之间的路径,路径上的分支个数称 ...

  8. 赫夫曼树建立c语言源程序编译结果详细解释,c语言构建哈夫曼树(附运行结果图)[本站推荐]...

    #include#include#include int m,s1,s2; typedef struct { unsigned int weight; unsigned int parent,lchi ...

  9. Huffman Tree哈夫曼树权值路径长度WPL计算,binarytree ,Python

    Huffman Tree哈夫曼树(霍夫曼树.赫夫曼树)权值路径长度WPL计算,binarytree ,Python 计算定义:把构建成功的哈夫曼树的每一个边缘节点(叶子)值乘以该节点到根的路径长度,最 ...

最新文章

  1. “偷鸡”不成的马斯克,终于丢掉了自己的“王位”
  2. XAMPP的MYSQL无法启动 -This may be due to a blocked port, missing dependencies,
  3. Net分布式系统之四:RabbitMQ消息队列应用
  4. 少儿编程100讲轻松学python(九)-python如何判断字符串是否为整数
  5. 绿得发娇的企业即时通讯软件
  6. 论文中怎么引用yolo_论文中怎么加入脚注,并且对脚注的序号、位置、格式进行调整...
  7. 4.4 Triplet 损失
  8. HTML meta元素
  9. 关于virtual pc安装Redhat
  10. 怎样利用php记录时间差,使用PHP计算出时间差的实现方法
  11. 微信开发-点击链接自己主动加入关注
  12. 今天许多的家庭有计算机英语,高一上学期英语作文范文
  13. 2018年10月7日虚拟机出现无法连接MKS错误提示和docx, rtf类型文件简介
  14. JavaScript随机方块
  15. python barplot宽度,如何在seaborn barplot上设置宽度
  16. 使用python包scanpy读取单细胞h5ad文件
  17. 【AD】原理图放置差分对,报错Missing Negative Net for differential pair
  18. 第一回 开篇 D3D渲染流程简介
  19. 如何用命令ping计算机型号,怎么修改cmd中ping命令的数据包大小?
  20. 电商网站购物车存储方式

热门文章

  1. 搜索引擎实现关键词高亮显示
  2. 别让家长群过了保质期
  3. JQuery基本操作 JQueryCSS操作 JQuery筛选选择器 JQuery筛选方法 JQuery效果
  4. css()用法,jQuery的css()方法用法实例
  5. EXC_RETURN
  6. 攻防世界crypto新手练习区通关教程
  7. STM32 HAL库 PWM+DMA 驱动WS2812B彩灯(STM32F030F4P6)
  8. 热血传奇手机版法师PK怎么样 热血传奇法师PK技巧
  9. 赚钱,能治愈一切矫情
  10. 上海通用计算机,上海市高校计算机等级考试通用平台