1、哈夫曼树及其构建
哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+...+ Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。
他的构建方式为:
首先先将离散节点从小到大升序排序
第二从离散节点中在挑选排序前两个节点当做一个新的父节点的两个子节点
第三从离散的节点中去除刚刚使用的两个节点
第四重复第二和第三步骤,直到所有离散节点剔除完毕。哈夫曼树就构建完成
2、哈夫曼树的编码方式
遵循左子树编号为0,右子树编号为1的方式
3、实现哈弗曼树的构建,遍历,编码
package Huffman; public class Node<T> { // 数据 T data; // 权重 int power; //编码,初始化为空 String coding = ""; Node<T> leftNode; Node<T> rightNode; public Node(T data,int power) { this.power = power; this.data = data; } public String toString() { // TODO Auto-generated method stub return "[data:" + data + " power:" + power + "]"; } @SuppressWarnings("unchecked") public boolean compareTo(Node node) { if (this.power < node.power) { return true; } return false; } public Node<T> getLeftNode() { return leftNode; } public void setLeftNode(Node<T> leftNode) { this.leftNode = leftNode; } public Node<T> getRightNode() { return rightNode; } public void setRightNode(Node<T> rightNode) { this.rightNode = rightNode; } public String getCoding() { return coding; } public void setCoding(String coding) { this.coding = coding; } }
创建哈夫曼树
/** * 创建哈夫曼树 * * @param list * @return */ @SuppressWarnings("unchecked") public static Node createHuffmanTree(List<Node> list) { while (list.size() > 1) { sort(list); //实例化左节点,此时list中存储的已经是排好序的数据 Node left = list.get(list.size() - 1); //实例化右节点 Node right = list.get(list.size() - 2); //构造父节点,节点中存储的字符为空,权值为两子树权值之和 Node parent = new Node(null,left.power + right.power); //将两子节点与parent连接 parent.leftNode = left; parent.rightNode = right; //把最小的两个删除 list.remove(list.size() - 1); list.remove(list.size() - 1); //将parent添加到队列中 list.add(parent); } //返回第一个节点 return list.get(0); }
**关于list.remove(int i);
是 java.util.List<E>中的一种方法,其中List<E>接口是有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
它允许重复的元素存在。
它中间一些常用的方法
boolean |
add(E e) 向列表的尾部添加指定的元素(可选操作)。 |
void |
clear() 从列表中移除所有元素(可选操作)。 |