赫夫曼树

定义:

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

算法思想:

由于赫夫曼树的构造决定了树中没有度为1的节点,则一颗有n个叶子节点的赫夫曼树共有2n-1个节点。则可以将其存储在容量为2n-1的数组中。
节点存储可以表示为

template<typename T>
struct HTnode
{T weitht;int parent, lchild, rchild;
};

其中parent、lchild、rchild之所以是int型是因为存放的是数组的下标。
赫夫曼树的实现可分为两大部分(叶子节点为n):
(1)初始化。将所有单元中的双亲、左孩子、右孩子初始化为0,再将n个叶子节点的权值初始化。
(2)通过n-1次的选择、删除、合并、来创建赫夫曼树:选择是从当前森林中选择双亲为0且权值最小的两个树根节点s1,s2.删除是指将节点s1,s2的双亲改为非0,合并就是讲s1,s2的权值加起来作为一个新节点的权值依次存入到数组的第n个之后的单元中。

求解最优WPL:

构造完赫夫曼树之后,此时赫夫曼树的WPL即是最小的。WPL等于树中所有叶子节点的带权路径长度之和。因此,需要先求出一个叶子节点的带权路径长度,也就是从该节点到树根节点之间的路径长度与节点上权的乘积。需要明白,此时数组中节点的parent为0的即是根节点。

C++代码实现:

#pragma once
#include <vector>
using namespace std;template<typename T>
struct HTnode
{T weitht;int parent, lchild, rchild;
};
/*** 赫夫曼树的C++实现* @author  wzx* @data    2019年3月16日*/
template <typename type>
class HuffmanTree
{
public:HuffmanTree();HuffmanTree(int[], int);~HuffmanTree()=default;//提供获取赫夫曼树的带权路径长度接口int getWPL();
private:int m_HuffmanTreeLength; ; //指示赫夫曼树中的叶子节点的数量vector <HTnode<type>> hTnodes;//在vector下标从0到k中找到双亲节点为0,且权值最小的两个节点void select(int k, int &s1, int &s2); void createHuffmanTree();
};
template <typename type>
HuffmanTree<type>::HuffmanTree():m_HuffmanTreeLength(0)
{}
template <typename type>
HuffmanTree<type>::HuffmanTree(int weights[],int nLength)
{for (int i{}; i < nLength; ++i){HTnode<type> hTnode = { weights[i],0,0,0 };hTnodes.push_back(hTnode);}for (int i{ nLength }; i < nLength * 2 - 1; ++i){HTnode<type> hTnode = {0,0,0,0};hTnodes.push_back(hTnode);}m_HuffmanTreeLength = nLength;createHuffmanTree();
}
template <typename type>
void HuffmanTree<type>::select(int k, int &s1, int &s2)
{int firstMinWeight = hTnodes.at(0).weitht;s1= 0;//找到第一个权值最小的节点for (int i=0; i <= k; ++i){if ((firstMinWeight > hTnodes.at(i).weitht)&&(hTnodes.at(i).parent == 0)){firstMinWeight = hTnodes.at(i).weitht;s1 = i;}}//找到第二个权值最小的节点//快速排序,找到符合条件的secMinWeight的初始值int   secMinWeight = 0;int j = 0;while (hTnodes.at(j).parent != 0||j==s1){++j;}secMinWeight = hTnodes.at(j).weitht;s2 = j;for (int i = 0; i <=k; ++i){if(i==s1)continue;else{if ((secMinWeight > hTnodes.at(i).weitht) && (hTnodes.at(i).parent == 0)){secMinWeight = hTnodes.at(i).weitht;s2 = i;}}}
}template <typename type>
void HuffmanTree<type>::createHuffmanTree()
{int s1 = 0, s2 = 0;for (int i = m_HuffmanTreeLength; i < 2 * m_HuffmanTreeLength - 1; ++i){select(i - 1, s1, s2);hTnodes[s1].parent = i;hTnodes[s2].parent = i;hTnodes[i].lchild = s1;hTnodes[i].rchild = s2;hTnodes[i].weitht = hTnodes[s1].weitht + hTnodes[s2].weitht;}
}template <typename type>
int HuffmanTree<type>::getWPL()
{int total=0;if (m_HuffmanTreeLength <= 1)return -1;else{for (int i{}; i < m_HuffmanTreeLength; ++i){int count = 0;int f = hTnodes[i].parent;while (f != 0){++count;f = hTnodes[f].parent;}total += count * hTnodes[i].weitht;}return total;}
}

赫夫曼树及求解最小WPL的实现相关推荐

  1. 数据结构与算法——赫夫曼树基本实现

    目录 一.赫夫曼树 1.1 基本介绍 1.2 赫夫曼树创建步骤图解 1.3  代码实现 二.赫夫曼编码 2.1 基本介绍 2.1.1  通讯领域 - 定长编码 - 举例说明 2.1.2  通讯领域 - ...

  2. 由二叉树构造赫夫曼树

    赫夫曼树: 假设有n个权值{w1,w2,w3....},试构造一棵具有 n个叶子节点的二叉树,每个叶子节点带权为wi,则其中 带权路径长度最小的二叉树称为最优二叉树或者叫赫夫曼树. 构造赫夫曼树: 假 ...

  3. 赫夫曼树(WPL最小树)

    13.4 赫夫曼树 基本介绍: 给定 n 个权值作为 n 个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,成这样的二叉树为 最优二叉树, 也成为 赫夫曼树(Huffman Tree ...

  4. 三十、赫夫曼树的设计与代码实现

    一.基本介绍 给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这样的二叉树为 最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍 ...

  5. 【赫夫曼树详解】赫夫曼树简介及java代码实现-数据结构07

    赫夫曼树(最优二叉树) 1. 简介 定义: 赫夫曼树是n个带权叶子结点构成的所有二叉树中,带权路径长度(WPL)最小的二叉树. 叶子结点的带权路径: 叶子结点权值*到根节点的路径长度(叶结点的层数) ...

  6. 数据结构 - 赫夫曼树

    wpl最小的就是赫夫曼树(所有叶子节点的带权路径长度之和最小) 写出来两个节点连接,然后循环就可以了 package tree.huffmantree;import java.util.ArrayLi ...

  7. 6.6.1最优二叉树(赫夫曼树)

    首先我们来看一个伪代码.这个是代表成绩的等级. 然后我们知道,每一次高考,学生的成绩分布应该接近某个比例,现在我们假如分别规律如下: 为此可以作出下面的这个树. 我们发现,概率分布主要是在70-79, ...

  8. 【Java数据结构】赫夫曼树

    哈弗曼树 哈弗曼树定义 哈弗曼树示例 哈弗曼树代码实现 哈弗曼树定义 给定 N 个权值作为 N 个叶子结点,构造一棵二叉树,若该树的带权路径长度(WPL)达到最小,称这样的二叉树为最优二叉树,也称为哈 ...

  9. 赫夫曼树的定义及原理

    参考<大话数据结构>        以学生成绩为例进行分析,正常的学生成绩的分布范围如下: 下面的图是普通的学生成绩判断,粗略的看什么问题,可是通常都认为,一张好的考卷应该是让学生的成绩大 ...

最新文章

  1. Windows API入门系列之七 -完善MessageBox
  2. 用jquery实现html5的placeholder功能
  3. 人月神话阅读笔记(二)
  4. teleport 组件的作用_人脸识别综述! 覆盖人脸检测,预处理和特征表示三大核心组件!...
  5. 继承20161223
  6. 【HUAWEI Mate30】抽奖啦!华为IoT新福利上线!
  7. 如何在 Zabbix 执行远程主机的脚本或指令?如何用 Zabbix 监控网站的访问量?
  8. 串口调试助手fx2n_串口调试助手发送控制台达PLC命令
  9. 希赛网软考学院将会使系分大大贬值
  10. [寒江孤叶丶的CrossApp之旅_07][入门系列]CrossApp中信息框CAAlertView的使用
  11. 08cms cecore.cls.php,08CMS 变量覆盖导致getshell 等问题
  12. 2018网络小说年度热词盘点
  13. 【深度学习】9:CNN实现olivettifaces人脸数据库识别
  14. 教你在线免费PDF转Word,建议收藏
  15. 企业云服务器的选择与配置指南
  16. 如何使用R批量处理文件
  17. 安装pycrypto,windows10,全解
  18. Web TOP10漏洞之sql注入
  19. 利用FME自动生成CAD图框
  20. 使用vscode编辑vue模板

热门文章

  1. spss 卡方检验,Logistic回归方法
  2. python中如何输入多行文字_python中怎么输入多行字符串 | 学会python
  3. 数据结构进阶篇,回文字符串专题
  4. php抓取公众号信息
  5. vs2013发布网页_网页设计:2013年值得关注的20个最热门趋势
  6. 谷歌无法保持登录状态
  7. 空调维修加氟维修移机制冷安装服务
  8. 安信可ESP-07S_12F_12S 腾讯云固件使用文档
  9. 智能投顾发展及相关信息
  10. Gemini Blueprint参考文档 第9章 服务注册表