最优前缀码
1. 问题
给定字符集C={x1, x2, …, xn}和每个字符的频率f(xi),求关于 C 的一个最优前缀码。
2. 解析
1.根据给定的n个权值{w1,w2,…,wn}构成n棵二叉树的合集F={T1, T2, …, Tn}, 其中每棵二叉树Ti中只有一个带权为wi根结点,其左右子树均为空。
2.在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左右子树上根结点的权值之和。
3.在F中删除这两棵树,同时将其新得到的二叉树加入F中。
4.重复2和3步骤,直到F只含一棵树为止。这棵树就是哈夫曼树。
5.规定哈夫曼树的左分支为0,右分支为1,从根结点到叶子结点所经过的路径分支组成的0和1的序列便为该结点对应字符的编码。
3. 设计
PriorityQueue<HuffmanNode> q =
new PriorityQueue<HuffmanNode>(n, new MyComparator());
for(int i = 0; i < n; i++){
HuffmanNode hn = new HuffmanNode();
hn.c = charArray[i];
hn.weight = charFreq[i];
hn.left = null;
hn.right = null;
q.add(hn);
}
HuffmanNode root = null;
while(q.size() > 1){
HuffmanNode x = q.peek();
q.poll();
HuffmanNode y = q.peek();
q.poll();
HuffmanNode temp = new HuffmanNode();
temp.c = '-';
temp.weight = x.weight+y.weight;
temp.left = x;
temp.right = y;
root = temp;
q.add(temp);
}
4. 分析
O(nlogn)频率排序;for 循环 O(n),插入操作 O(logn),算法时间复杂
度是 O(nlogn)
5. 源码
https://github.com/Marshmello11/Algorithm/tree/master/Experiment_11