【树】哈夫曼树及其构造

1.哈夫曼树的基本概念
  1. 结点间的路径路径长度
    路径是指从一个结点到另一个结点之间的分支序列。
    路径长度是指从一个结点到另一个结点所经过的分支数目。
  2. 结点的带权路径长度
    在实际的应用中,给树的每个结点赋予一个具有某种实际意义的实数,称该实数为这个结点的权
    在树型结构中,把从树根到某一结点的路径长度与该结点的权的乘积,叫做该结点的带权路径长度。
  3. 树的带权路径长度
    树的带权路径长度为树中从根到所有叶子结点的各个带权路径长度之和,通常记为:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 构造哈夫曼树

哈夫曼树:它是由 n 个带权叶子结点构成的所有二叉树中带权路径长度最短的二叉树。因为这种树最早由哈夫曼(Huffman)研究,所以称为哈夫曼树,又叫最优二叉树

  • 构造哈夫曼树的算法步骤如下:

在这里插入图片描述

在这里插入图片描述

直观地看,先选择权小的,所以权小的结点被放置在树的较深层,而权较大的离根较近,这样自然在哈夫曼树中权越大叶子离根越近,这样一来,在计算树的带权路径长度时,自然会具有最小带权路径长度,这种生成算法就是一种典型的贪心法。

3. 哈夫曼树的类型定义

在这里插入图片描述

(2)哈夫曼树的类型定义
用静态三叉链表实现的哈夫曼树类型定义如下:

#define N 20        /* 叶子结点的最大值。*/
#define M 2 * N - 1 /* 所有结点的最大值。*/
typedef struct
{
  int weight;                 /* 结点的权值*/
  int parent;                 /* 双亲的下标*/
  int LChild;                 /* 左孩子结点的下标*/
  int RChild;                 /* 右孩子结点的下标*/
} HTNode, HuffmanTree[M + 1]; /* HuffmanTree 是一个结构数组类型,0 号单元不 用。 */

4.哈夫曼树的算法实现
void CrtHuffmanTree(HuffmanTree ht, int w[], int n)
{ /*构造哈夫曼树 ht[M+1], w[ ]存放 n 个权值。*/
  for (i = 1; i <= n; i++)
    ht[i] = {w[i], 0, 0, 0}; /* 1 ~ n 号单元存放叶子结点,初始化*/
  m = 2 * n - 1;
  for (i = n + 1; i <= m; i++)
    ht[i] = {0, 0, 0, 0}; /* n+1 ~ m 号单元存放非叶结点,初始化 */
  /*————————————初始化完毕!对应算法步骤 1—————————*/
  for (i = n + 1; i <= m; i++) /*创建非叶结点,建哈夫曼树*/
  {
    select(ht, i - 1, s1, s2); /* 在 ht[1] ~ ht[i-1] 的范围内选择两个 parent 为 0 且
weight 最小的结点,其序号分别赋值给 s1、s2 返回 */
    ht[i].weight = ht[s1].weight + ht[s2].weight;
    ht[s1].parent = i;
    ht[s2].parent = i;
    ht[i].LChild = s1;
    ht[i].RChild = s2;
  } /*哈夫曼树建立完毕*/
}

该算法分成两大部分,其中第一部分是初始化,先初始化 ht 的前 1~n 号元素,存放叶子结点(相当初始森林),它们都没有双亲与孩子。再初始化 ht 的后 n-1 个(从 n+1~2n-1)非叶结点元素;第二部分为实施选择、删除合并 n-1 次(相当步骤(2)~(4)):选择是从当前森林中(在森林中树的根结点的双亲为 0)选择两棵根的权值最小的树;删除合并是将选到的两棵树的根权和存入 ht 的当前最前面的空闲元素中(相当于合并树中新结点),并置入相应的双亲与孩子的位置指示。

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值