赫夫曼树又称为最优树、最优二叉树
赫夫曼树百度百科 | https://baike.baidu.com/item/%E5%93%88%E5%A4%AB%E6%9B%BC%E6%A0%91/2305769?fromtitle=%E8%B5%AB%E5%A4%AB%E6%9B%BC%E6%A0%91&fromid=7406794&fr=aladdin |
---|---|
📚赫夫曼树相关的名词
(1).路径
📑一个结点到另外一个结点的通路成为路径
(2).路径长度
📑通路中分支的数目称为路径长度,若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。
(3).结点的权
📑若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权
(4).结点的带权路径长度
📑从根结点到该结点之间的路径长度与该结点的权的乘积。
(5).树的带权路径长度
📑树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。
赫夫曼树的特点
在构建哈弗曼树时,要使树的带权路径长度最小,只需要遵循一个原则,那就是:权重越大的结点离树根越近。在图 1中,因为结点 a 的权值最大,所以理应直接作为根结点的孩子结点。
📚赫夫曼树的构建流程分析
以该结点集合[5,29,7,8,14,23,3,11]为例
1.讲每个结点存放到集合当中
2.对该集合进行排序(按照权值大小)
3.从集合中取出两个结点,创建一个新的结点作为它们的父节点,父节点的权值等于两个子节点的之和。
4.讲父节点加入到集合当中,从集合中移除这两个子结点
5.周而复始的执行1~4步即可,直到list.size <= 1;此时集合中剩下最后一个结点,而这个结点就是哈夫曼树的根节点(100)
📚源代码
public class HuffmanTree {
//测试
public static void main(String[] args) {
int[] arr = {13, 7, 8, 3, 29, 6, 1};
HuffNode root = buildHuffmanTree(arr);
preErgodic(root);
}
/**
*1.首先遍历数组,将权值依次封装到HuffNode对象中,并加入到List集合
*2.由于实现类Comparable接口,所以使用Collections.sort进行集合排序
*3.分别从集合中取出两个结点,然后创建一个新的父节点(父节点的权值即为两个子节点的权值之和,将left和right指针分别指向两个子节点。
*4.将父节点加入到list集合中
*5.循环1-4步,直到size == 1 ,也就是集合中只剩下哈夫曼树的根节点
*/
private static HuffNode buildHuffmanTree(int[] arr) {
List<HuffNode> list = new ArrayList<>();
for (int value : arr) {
list.add(new HuffNode(value));
}
while (list.size() > 1) {
Collections.sort(list);
HuffNode leftNode = list.remove(0);
HuffNode rightNode = list.remove(0);
HuffNode root = new HuffNode(leftNode.value + rightNode.value);
root.left = leftNode;
root.right = rightNode;
list.add(root);
}
return list.remove(0);
}
//对构建好的哈夫曼树进行先序遍历
private static void preErgodic(HuffNode root) {
if (root == null) {
return;
}
System.out.print(root.value + "->");
preErgodic(root.left);
preErgodic(root.right);
}
}
/**
*集成Comparable接口,实现其中的compareTo方法;方便后序使用Collections.sort进行排序
*/
class HuffNode implements Comparable<HuffNode> {
public int value; //结点的权值
public HuffNode left;//结点的左指针
public HuffNode right; //结点的右指针
public HuffNode(int value) {
this.value = value;
}
//this.value-o.value表示进行升序排序
@Override
public int compareTo(HuffNode o) {
return this.value - o.value;
}
}