首页 > 其他分享 >【哈夫曼树】

【哈夫曼树】

时间:2024-12-09 15:04:07浏览次数:7  
标签:结点 哈夫曼 路径 权值 长度 2n

1. 哈夫曼树的基本概念

哈夫曼树又称最优二叉树(最优树),是一类带权路径长度最短的树。

路径:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径。

路径长度:路径上分支的数目。

树的路径长度:从树根到每个结点的路径长度之和。


权:分为结点权和边权,结点权是结点上的权,边权是边上权。

结点的带权路径长度:从该结点到树根的路径长度乘以该结点的权值。

树的带权路径长度:树中每一个叶子结点的带权路径长度之和,即WPL = \sum_{1}^{n}w_{i}l_{i}


哈夫曼树:带权路径长度WPL最小(最小带权路径长度)的二叉树称作最优二叉树或哈夫曼树。


2. 哈夫曼树的算法实现

哈夫曼树中是没有度为1的结点,则一棵有 n 个叶子结点的哈夫曼树共有 2n - 1个结点

因此可以用存储大小为 2n - 1的一维数组中。

2.1 哈夫曼树的存储结构

typedef struct{
	int weight;                   //结点的权值 
	int parent,lchild,rchild;    //结点的双亲,左孩子,右孩子的下标 
}HTNode,* HuffmanTree;          //动态分配数组存储哈夫曼树

2.2 构造哈夫曼树

【算法步骤】

构造哈夫曼树算法的实现可以分成两大部分:(1)初始化 (2)创建哈夫曼树

(1)初始化

1. 确定哈夫曼树中的结点个数 m = 2n - 1;(其中,n为叶子节点的个数),

2. 动态分配 2n 个存储单元(0号单元未使用,HT[m] 表示根节点),

3. 从1到2n-1个所有单元中双亲、左孩子、右孩子的下标初始化为 0;

4. 依次输入 n 个叶子结点的权值。


(2)创建哈夫曼树

共有 n 个叶子结点,循环 n - 1次,通过n - 1次的选择、删除、合并操作来创建哈夫曼树。

1. 选择:从当前数中选择双亲为 0,且权值最小的两个树根结点,

2. 删除:将选出了来的两个结点的双亲改为非0,

3. 合并:最小两个结点的权值和作为一个新结点的权值依次存入到数组的第 n + 1之后的单元中,同时记录左孩子和右孩子的信息。

【算法描述】

void CreateHuffanTree(HuffmanTree &HT , int n){
	int m = 2 * n - 1;   //确定哈夫曼数中的结点个数
	HT = new HTNode[m + 1];   //动态分配 2n 个存储单元(2n == m + 1)
	
	for(int i = 1; i <= m; i++){     //将所有结点进行初始化 
		HT[i].parent = 0;
		HT[i].lchild = 0;
		HT[i].rchild = 0;
	} 
	for(int i = 1; i <= n; i++){    //输入 n 个叶子结点的权值 
		cin >> HT[i].weight;     
	}

   ----------初始化操作结束------------- 

	//创建哈夫曼树 
	for(int i = n + 1; i <= m; i++){
		// 1.选择两个权值最小的根节点
		int s1,s2;
		Select(HT, i - 1, s1,s2);       //返回的是两个最小权值结点的下标 
		
	    //2.从森林中删除两个树
		HT[s1].parent = i;
		HT[s2].parent = i;
		
		//3.合并两个结点的权值,并加入到 n + 1个单元中,且指定左孩子、右孩子 
		HT[i].left = s1;
		HT[i].right = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight ;  
	} 
} 

标签:结点,哈夫曼,路径,权值,长度,2n
From: https://blog.csdn.net/2301_81182847/article/details/144308989

相关文章

  • 【数据结构】哈夫曼树
    哈夫曼树路径长度:从树中一个结点到另一个结点之间的分支构成这两个节点之间的路径,路径上的分支数目称为路径长度树的带权路径长度:树中所有叶子结点的带权路径长度之和,通常记为WPL=∑......
  • 数据结构——哈夫曼编码
    目录1、哈夫曼编码定义2、问题描述3、逐步分析1)涉及操作2)代码实现4、代码整合1、哈夫曼编码定义哈夫曼编码(HuffmanCoding)是一种用于无损数据压缩的熵编码算法。它是由大卫・哈夫曼(DavidA.Huffman)在1952年发明的。其基本思想是根据字符在数据中出现的频率来分......
  • Task A2 哈夫曼树的应用
    【题目描述】PTA(数据结构与算法题目集7-29)农夫要修理牧场的一段栅栏,他测量了栅栏,发现需要N块木头,每块木头长度为整数Li个长度单位,于是他购买了一条很长的、能锯成N块的木头,即该木头的长度是Li的总和。但是农夫自己没有锯子,请人锯木的酬金跟这段木头的长度成正比。为简......
  • 【数据结构】哈夫曼树的构建和哈夫曼编码
    说明本篇为笔者学习随记,供学习和复习使用结构体定义typedefstruct{ intweight=0; intparent=0,lchild=0,rchild=0;}HTNode;此处=0可使结构体在构建时就自动初始化typedefchar**HuffmanCode;把多重指针换成HuffmanCode 哈夫曼树的构建构建思路:a)初始化哈夫......
  • 【算法竞赛】二叉树和哈夫曼树
    树是非线性数据结构,它能很好地描述数据的层次关系。树这种结构的现实场景很常见,如文件目录、书本的目录就是典型的树形结构。二叉树是最常用的树形结构,特别适合编码,常常将一般的树转换为二叉树来处理。本节介绍二叉树的定义和存储。哈夫曼(Huffman)树是二叉树的一个......
  • 信息学奥赛初赛天天练-89-CSP-S2023基础题1-linux常用命令、完全平方数、稀疏图、队列
    PDF文档公众号回复关键字:202409142023CSP-S选择题单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项)1在Linux系统终端中,以下哪个命令用于创建一个新的目录?()AnewdirBmkdirCcreateDmkfold2从0,1,2,3,4中选取4个数字,能组成(......
  • 哈夫曼树和哈夫曼编码详解(包含Java代码实现)
    目录什么是哈夫曼树?如何构造哈夫曼树?构造过程代码实现哈夫曼树的结构构建哈夫曼树并计算WPL值测试代码什么是哈夫曼编码?如何构建哈夫曼编码?构建过程代码实现什么是哈夫曼树?哈夫曼树又称为最优树,是一类带权路径长度最短的树,在实际中有着广泛的应用。介绍哈夫曼树......
  • 【数据结构】【模板】哈夫曼树
    哈夫曼树定义带权路径长度:结点的权值乘以结点到跟的距离。树上所有结点带权路径长度之和最小的二叉树称为哈夫曼树。性质哈夫曼是满二叉树。来自维基百科:原序列构成哈夫曼树的所有叶子结点。离根结点越近,点权越大。非叶子结点的点权之和就是所有叶子结点的带权路径之和......
  • 数据结构----树,二叉树,哈夫曼树相关概念及其实现
    树形结构概述1分层逻辑结构所谓的分层逻辑结构,也称为树形逻辑结构关系,是数据结构中的一种逻辑关系结构,在该逻辑结构关系中的数据元素之间满足一对多的逻辑结构关系:起始数据节点有且仅有一个,没有直接前驱,可以有多个直接后继;末尾数据节点可以多个,有且仅有一个直接前驱,......
  • 哈夫曼树学习笔记
    哈夫曼树学习笔记定义设二叉树具有\(n\)个带权叶结点,从根结点到各叶结点的路径长度与相应叶节点权值的乘积之和称为树的带权路径长度(WeightedPathLengthofTree,WPL)。设\(w_i\)为二叉树第\(i\)个叶结点的权值,\(l_i\)为从根结点到第\(i\)个叶结点的路径长度,则WPL......