# 算法导论示例-Huffman

1398人阅读 评论(1)

/**
* Introduction to Algorithms, Second Edition
* 16.3 Huffman codes
*
* @author 土豆爸爸
*
*/
import java.util.List;

public class Huffman {
static class Node implements IPriorityQueueElement<Integer>{
Node left; //左子节点
Node right; //右子节点
Integer f; //频率
char c; //字符

public Node() {}

public Node(char c, Integer f) {
this.c = c;
this.f = f;
}
public Integer getKey() {
return f;
}
}

public static Node encode(List<Node> nodes) {
int n = nodes.size();

//根据频率生成最小优先队列
MinPriorityQueue<Integer, Node> queue = new MinPriorityQueue<Integer, Node>(n);
for(Node node : nodes) {
queue.insert(node);
}

for(int i = 0; i < n - 1; i++) {
Node node = new Node();
Node x = queue.extractMin(); //取出队列的前两个元素
Node y = queue.extractMin();
node.left = x; //将取出两个元素作为新节点的子节点
node.right = y;
node.f = x.f + y.f; //新节点的频率是子节点频率之和
queue.insert(node); //插入到队列中
}

return queue.extractMin();
}
}

/**
* Introduction to Algorithms, Second Edition
* 6.5 min-priority queue
*
* @author 土豆爸爸
*
*/
import java.util.EmptyStackException;

public class MinPriorityQueue<KeyType extends Comparable<KeyType>, T extends IPriorityQueueElement<KeyType>> {
T[] array;

int heapSize;

/**
* 构造函数
* @param size 初始数组大小
*/
@SuppressWarnings("unchecked")
public MinPriorityQueue(int size) {
array = (T[]) new IPriorityQueueElement[size];
}

/**
* 获取当前heap中的最小值
*
* @return 最小值
*/
public T minimum() {
return array[0];
}

/**
* 获取当前heap中的最小值,并从heap中删除最小值
* @return 最小值
*/
public T extractMin() {
if (heapSize < 1) {
throw new EmptyStackException();
}
T min = array[0];
array[0] = array[heapSize - 1];
heapSize--;
minHeapify(0);
return min;
}

/**
* 插入一个元素
* @param e
*/
@SuppressWarnings("unchecked")
public void insert(T e) {
if (heapSize == array.length) {
T[] newArray = (T[]) new IPriorityQueueElement[array.length * 2];
System.arraycopy(array, 0, newArray, 0, array.length);
array = newArray;
}
int i = heapSize++;
array[i] = e;
int p = parent(i); // 父结点索引
while (i > 0 && array[p].getKey().compareTo(array[i].getKey()) > 0) {
T temp = array[i];
array[i] = array[p];
array[p] = temp;
i = p;
p = parent(i);
}
}

/**
* 使数组的第i个元素按max heap规则重排
*
* @param i
*            元素索引
*/
private void minHeapify(int i) {
int l = left(i);
int r = right(i);
int smallest; // 当前结点/左子结点/右子结点中最大值的索引
if (l < heapSize && array[l].getKey().compareTo(array[i].getKey()) < 0) {
smallest = l;
} else {
smallest = i;
}

if (r < heapSize && array[r].getKey().compareTo(array[smallest].getKey()) < 0) {
smallest = r;
}

if (smallest != i) {
// 如果最大值不是当前结点,进行交换
T temp = array[i];
array[i] = array[smallest];
array[smallest] = temp;
// 递归调用,直到当前结点比其子结点大
minHeapify(smallest);
}

}

/**
* 计算结点索引为i的元素的父结点的索引
*
* @param i
*            当前索引
* @return 父结点的索引
*/
private int parent(int i) {
return (i + 1) / 2 - 1;
}

/**
* 计算结点索引为i的元素的左子结点的索引
*
* @param i
*            当前索引
* @return 左子结点的索引
*/
private int left(int i) {
return 2 * i + 1;
}

/**
* 计算结点索引为i的元素的右子结点的索引
*
* @param i
*            当前索引
* @return 右子结点的索引
*/
private int right(int i) {
return 2 * i + 2;
}
}

public interface IPriorityQueueElement<KeyType extends Comparable<KeyType>>{
KeyType getKey();
}

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

public class HuffmanTest extends TestCase {
public void testEncode() {
List<Huffman.Node> c = new ArrayList<Huffman.Node>();

Huffman.Node root = Huffman.encode(c);
assertEquals(100, root.f.intValue());
assertEquals(45, root.left.f.intValue());
assertEquals('a', root.left.c);
assertEquals(55, root.right.f.intValue());
assertEquals('c', root.right.left.left.c);
assertEquals('b', root.right.left.right.c);
assertEquals('f', root.right.right.left.left.c);
assertEquals('e', root.right.right.left.right.c);
assertEquals('d', root.right.right.right.c);
}
}


0
0

【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐（算法+实战）--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：137911次
• 积分：2086
• 等级：
• 排名：第18232名
• 原创：62篇
• 转载：0篇
• 译文：4篇
• 评论：47条
评论排行
最新评论