哈夫曼树

本文介绍了哈夫曼树的概念,包括路径长度、节点路径长度、权值、带权路径长度和最优二叉树的定义。重点阐述了如何构造最优二叉树,通过新建节点类,将数据封装成节点并放入容器中,然后循环寻找权值最小的节点进行合并,最终生成哈夫曼树。同时提供了一个Java实现的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

哈夫曼树

路径长度:

节点路径长度:从一个节点(根节点)到另外一个节点所经过的路径的分支数目

树的路径长度:指树种所有节点的路径长度之和

权值:

指的是所有叶子节点的date域,存放一个数值,用来表示当前叶子节点的数据,那这个值就是权值

带权路径长度:

所有叶子节点的带权路径长度之和

最优二叉树:

1、通过所有权值节点,形成一个二叉树,最终这个二叉树的带权路径最小,则此二叉树是哈夫曼树(最优二叉树)

2、树的结构不止一个,同一层的节点,可以左右替换

构造最优二叉树:

1、新建一个节点类

2把数据封装成节点,放到容器中,用于建立一个森林

3循环寻找权值最小的两个节点,用于构造新的节点

需要定义一个方法,来寻找当前节点插入到森林中的位置


哈夫曼树代码实现:


//****************************************************************************************//
public class HuffmNode {
private int date;
private HuffmNode left;
private HuffmNode right;

public HuffmNode(int date) {
this.date = date;
}

public int getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
public HuffmNode getLeft() {
return left;
}
public void setLeft(HuffmNode left) {
this.left = left;
}
public HuffmNode getRight() {
return right;
}
public void setRight(HuffmNode right) {
this.right = right;
}
}

//*********************************************************************************//

import java.util.LinkedList;


public class HuffmTree {
int[] dates = {2,1,7,6,9,4,3};
//用队列实现节点的封装
LinkedList<HuffmNode> nodeList = new LinkedList<HuffmNode>();
public HuffmNode createTree(){
//把数据封装成节点,放到容器中,用于建立一个森林
for (int i = 0; i < dates.length; i++) {
HuffmNode node = new HuffmNode(dates[i]);
//获取当前节点需要插入的位置
int index = getIndex(node.getDate());
//插入节点方式实现
nodeList.add(index,node);
}
//循环寻找权值最小的两个节点,用于构造新的节点
while(nodeList.size()>1){
HuffmNode firstNode = nodeList.removeFirst();
HuffmNode secondNode = nodeList.removeFirst();
//构造一个新的节点
HuffmNode fatherNode = new HuffmNode(firstNode.getDate()+secondNode.getDate());
fatherNode.setLeft(firstNode);
fatherNode.setRight(secondNode);
//获取当前父节点值在容器中的大小位置
int index = getIndex(fatherNode.getDate());
//把父节点放置到森林中
nodeList.add(index,fatherNode);
}
return nodeList.getFirst();
}

public int getIndex(int value){
//遍历容器
for (int i = 0; i < nodeList.size(); i++) {
HuffmNode node = nodeList.get(i);
//比较大小
if(value>node.getDate()){
continue;
}else{
return i;
}
}
return nodeList.size();
}

public void getCode(HuffmNode root,String code){
if(root.getLeft()!=null){
getCode(root.getLeft(),code+"0");
}
if(root.getRight()!=null){
getCode(root.getRight(),code+"1");
}
//判断当前节点是否为叶子节点
if(root.getLeft()==null&&root.getRight()==null){
System.out.println(code);
}
}
}






### 构建哈夫曼的方法 构建哈夫曼的过程基于贪心算法,其核心在于通过不断选取具有最小权重的节点来逐步形成最终的哈夫曼。具体过程如下: #### 初始化阶段 准备n个节点作为初始集合中的元素,每个节点代表一个字符及其对应的频率或权重,并且这些节点均视为独立的子。 #### 节点选择组合 从未被加入到新结构里的节点集中选出两个拥有最小权重值的节点A和B,创建一个新的内部节点C,该节点不对应任何实际意义的据项而是仅用于连接其他节点;设置C的左孩子指向A而右孩子则指向B,同时赋予C等于A+B两节点之和的新权重值[^2]。 #### 更新节点集 将已处理过的原节点A和B从候选列表里移除并将新建的父级节点C添加进去继续参后续的选择操作直到整个过程中只剩下最后一个未配对成功的根节点为止此时即完成了整棵哈夫曼的搭建工作[^1]。 ```python import heapq def huffman_tree(frequencies): heap = [[weight, [symbol, ""]] for symbol, weight in frequencies.items()] heapq.heapify(heap) while len(heap) > 1: lo = heapq.heappop(heap) hi = heapq.heappop(heap) for pair in lo[1:]: pair[1] = '0' + pair[1] for pair in hi[1:]: pair[1] = '1' + pair[1] heapq.heappush(heap, [lo[0]+hi[0]] + lo[1:] + hi[1:]) return sorted(heapq.heappop(heap)[1:], key=lambda p: (len(p[-1]), p)) # Example usage of the function to create a Huffman tree. frequencies_example = {'a': 45, 'b': 13, 'c': 12, 'd': 16, 'e': 9, 'f': 5} huffman_result = huffman_tree(frequencies_example) for char, code in huffman_result: print(f"{char}: {code}") ``` 上述Python代码实现了哈夫曼的创建逻辑,其中`heapq`模块用来维护优先队列以便高效获取当前剩余节点中权重最低的一对。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值