首页 > 其他分享 >哈夫曼树的构造

哈夫曼树的构造

时间:2023-02-17 15:32:42浏览次数:30  
标签:weight 哈夫曼 int ht 构造 权值 节点


    1 哈夫曼树的概念


在许多应用中经常将树中的节点赋予一个权值 , 从根节点到该节点之间的路径长度与该节点上的权值的乘积称为该节点的带权路径长度(WPL) , 树中所有叶子节点的带权路径长度之和称为该树的带权路径长度。

哈夫曼树的构造_权值

.其中no为叶节点的个数,wi和li分别表示第 i 个叶节点权值和根到它之间的路径长度 。

 

   在 

哈夫曼树的构造_结点_02

个带权叶节点构成的所有二叉树中,带权路径长度最小的称为哈夫曼树或者最优二叉树 。

 

    如下图为一哈夫曼树示意图。

哈夫曼树的构造_i++_03

 

2、构造哈夫曼树

假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:

(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);

(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;

(3)从森林中删除选取的两棵树,并将新树加入森林;

(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

 如:对 下图中的六个带权叶子结点来构造一棵哈夫曼树,步骤如下:

 

哈夫曼树的构造_i++_04

 

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
const int MAX = 1015 ;
typedef struct {
char data ;
int weight ;
int parent ;
int lchild ;
int rchild ;
}HTNode;
int n ;
void CreateHT(HTNode *ht , int n)
{
int lnode , rnode ;
double min1 ,min2 ;
for(int i = 0 ; i<2*n-1 ;i++) // 所有节点的相关域初值未 -1
ht[i].parent = ht[i].lchild = ht[i].rchild = -1 ;
for(int i = n ; i<2*n - 1 ;i++)
{
// 将每个非叶子节点放到 n ~ 2n-2 中
min1 = min2 = 99999 ;
lnode = rnode = -1 ;
// 每次在 ht[0...i-1] 中选取权值最小的两个节点
for(int k = 0 ; k<=i-1;k++)

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[i].weight = ht[lnode].weight + ht[rnode].weight ; // h[i]作为双亲
ht[i].lchild = lnode ;
ht[i].rchild = rnode ;
ht[lnode].parent = i ;
ht[rnode].parent = i ;

}
}
int main()
{
int n ;
HTNode h[MAX] ;
cin >>n ;
for(int i = 0 ; i<n ;i++)
cin >> h[i].weight;
CreateHT(h,n);
for(int i = 0 ; i<2*n-1 ;i++)
cout<<h[i].weight <<" ";

return 0 ;
}

 

 

标签:weight,哈夫曼,int,ht,构造,权值,节点
From: https://blog.51cto.com/u_15970235/6064294

相关文章

  • 哈夫曼树
    1.定义1.1哈夫曼树哈夫曼树是一种最基本的压缩编码方法。对于如图所示的两棵二叉树,每个叶子节点都带有权值:从树中一个结点到另一个结点之间的分支构成两个结点之间的......
  • 002.初始话Ioc容器——基于构造方法实例化对象(Bean)
    1.三种XML实例化Bean的配置方式  1.基于构造方法实例化对象  2.基于静态工厂实例化对象  3.基于工厂实例方法实例化对象2.详细讲解  2.1  基于构造方......
  • 47-代码块,构造器顺序问题
    基本介绍代码化块又称为初始化块,属于类中的成员[即是类的一部分],类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。但和方法不同,没有方法名,没有返回,没有参数,只有方法......
  • 如何使用php构造JAVA的包含数组元素的JSON对象
    提问: 最近做开发,接口是JAVA,这边使用PHP对接,接口要求一个字段是JSON对象,JSON对象中的字段是数组,格式如下:"result":{"JSON":{"ARRAY":[]......
  • C++构造函数的两种实现方式
    C++构造函数的两种实现方式下面两种方式等价structListNode{intval;ListNode*next;ListNode(val){intval=val;next=nullptr......
  • 构造器(有参、无参)
    构造器:就是和类名相同但无返回类型的方法。用于当前或某一对象的实例化,并将当前或某一对象返回。无参构造:1、如果使用new关键字实际上是调用无参构造器;2、无参构造往往是为......
  • 稳妥构造函数模式
    /*稳妥对象(durableobjects)*所谓稳妥对象,指的是没有公共属性,而且其方法也不引用this对象。*稳妥模式最适合在一些安全环境中(这些环境会禁止使用this和new),*或......
  • 寄生构造函数模式
    /*感觉没多大用记下得了*//**基本思维:*创建一个函数,该函数的作用仅是封装创建对象的代码,然后返回新创建的对象。*表面上看很像构造函数**/func......
  • 类的构造函数和析构函数
    构造函数和析构函数构造函数是类的入口函数析构函数是类的销毁函数1、构造函数a、构造函数默认是public类型的,如果定义private则定义外部不能进行对象的创建,所以只能是......
  • C++构造和析构
    category:cpp参考书籍:C++PrimerEssentialC++编译器:gcc/g++C++构造和析构构造函数名字和类名相同没有返回值构造函数是用来构造对象,构造对象时候必定调用构造函数不......