哈夫曼树又称最优二叉树
哈夫曼树的构造
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:
(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。
编程实现:
package binarytree;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
public class HuffmanTree<T> {
public class Node{
T data;
double weight;
Node lchild;
Node rchild;
public Node(T data, double weight) {
this.data = data;
this.weight = weight;
}
@Override
public String toString() {
return "Node [data=" + data + ", weight=" + weight + "]";
}
}
/**
* 构造哈夫曼树
* @param nodes节点集合
* @return 哈夫曼根节点
*/
public Node createTree(List<Node> nodes){
int size=nodes.size();
while (size>1) {
quickSort(nodes,0,size-1);
Node left=nodes.get(size-1);
Node right=nodes.get(size-2);
Node parent=new Node(null, left.weight+right.weight);
parent.lchild=left;
parent.rchild=right;
nodes.remove(size-1);
nodes.remove(size-2);
nodes.add(parent);
}
return nodes.get(0);
}
//降序排列的快速排序
private void quickSort(List<Node> nodes, int l, int u) {
if (l>=u) {
return;
}
Node temp=nodes.get(l); int i=l; int j=u;
while(i<j){
for (; i < j && nodes.get(i).weight>=temp.weight; i++);
for (; i < j && nodes.get(j).weight<temp.weight; j--);
if (i>j) {
break;
}
Collections.swap(nodes, i, j);
}
Collections.swap(nodes, j, l);
quickSort(nodes, l, j-1);
quickSort(nodes, j+1, u);
}
//广度优先遍历
public List<Node> breadthFrist(Node root){
Queue<Node> queue=new ArrayDeque<Node>();
List<Node> list=new ArrayList<Node>();
if (root!=null) {
queue.offer(root);
}
while (!queue.isEmpty()) {
list.add(queue.peek());
Node pNode=queue.poll();
if (pNode.lchild!=null) {
queue.offer(pNode.lchild);
}
if (pNode.rchild!=null) {
queue.offer(pNode.rchild);
}
}
return list;
}
}