数据结构:哈夫曼树

一、哈夫曼树的基本概念

  • 哈弗曼树:又称最优树,是一类带权路径长度最短的二叉树。
  • 路径:从树中一个节点到另一个节点之间的分支构成了这两个结点之间的路径。
  • (带权)路径长度:路径上的分支数目(带权)称作路径长度。
  • (带权)树的路径长度:从树根到每一个结点的路径长度(带权)之和。

二、哈夫曼树的构建方法

1、示例说明哈夫曼树的构造方法

已知 w= (5,29,7,8,14,23,3,11),利用这些结点构建哈弗曼树:
step1:从w中选出两个最小的结点(3,5),构建一个结点:{parent = 8;lchild = 3;rchild = 5;}。将(3,5)从w中去掉,加入(8),w变为(8,29,7,8,14,23,11)。
step2:重复step1,直到w中没有结点。
上述例子,哈弗曼树构建过程如下:
iteration1:(5,29,7,8,14,23,3,11) -pick-> (3,5) : {parent=9,lchild=3,rchild=5} -changed w-> (8,29,7,8,14,23,11)

iteration2:(8,29,7,8,14,23,11) -pick-> (7,8) : {parent=15,lchild=7,rchild=8{lchild=3,rchild=5}} -changed w->(8,29,15,14,23,11)

iteration3:(8,29,15,14,23,11) -pick-> (11,8) : {parent=19,lchild=8,rchild=9} -changed w->(19,29,15,14,23)

iteration4:(19,29,15,14,23) -pick-> (14,15) : {parent=29,lchild=14,rchild=15{lchild=7,rchild=8}} -changed w->(19,29,29,23)

iteration5:(19,29,29,23) -pick-> (19,23) : {parent=42,lchild=19,rchild=23} -changed w->(42,29,29)

iteration6:(42,29,29) -pick-> (29,29) : {parent=58,lchild=29,rchild=29{lchild=14,rchild=15{lchild=7,rchild=8}}} -changed w->(42,58)

iteration7:(42,58) : {parent=100,lchild=42,rchild=58{lchild=29,rchild=29{lchild=14,rchild=15{lchild=7,rchild=8}}}

result:

2、构造哈夫曼树 伪代码
2.1 哈夫曼树存储结构
typedef struct{
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
2.2 构造哈夫曼树
void CreateHuffmanTree(HuffmanTree &T,int n){
if(n<=1){return;}
m = 2n-1;
HT = HuffmanTree[m+1];
for(i=1;i<=n;++i){ //初始化权重
cin>>HT[i].weight = ch;
}
for(i=1;i<=m;++i){ //初始化HuffmanTree
HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;
}
//开始构建HuffmanTree
for(i=n+1;i<=m;++i){
Search(HT,i,s1,s2); //在HT[k](1<=k<=i-1)中搜索两个parent=0,且权重最小的结点,并将他们在HT中的序号返回给s1,s2;
H[s1].parent=i;H[s2].parent=i;
H[i].lchild=s1;H[i].rchild=s2;
H[i].weight=H[s1].weight + H[s2].weight;
}
}

参考资料:《数据结构》 严蔚敏

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sarah ฅʕ•̫͡•ʔฅ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值