package greedy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
public class Huffman {
private static final String dir = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,;/!?abcdefghijklmnopqrstuvwxyz";
private static Node[] nodeArray;
public static HashMap<Character, String> map = new HashMap<Character, String>();// 存放字符=>编码的key-value对
static {
nodeArray = new Node[dir.length() * 2 - 1];
for (int i = 0; i < dir.length(); i++) {
nodeArray[i] = new Node(dir.charAt(i), (int) (100 * Math.random() + 1), 0, -1, -1);
}
Arrays.sort(nodeArray, 0, dir.length() - 1, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return o1.weight - o2.weight;
}
});
initHuffmanTree();
}
private static void initHuffmanTree() {
int initLength = dir.length();
for (int i = 0; i < nodeArray.length - 2;) {
Node x = nodeArray[i];
Node y = nodeArray[i + 1];
Node parent = new Node(x.weight + y.weight, i + 1, i);
int j = i + 2;
while (j < initLength && nodeArray[j].weight <= parent.weight && nodeArray[j].weight != 0)
j++;
for (int k = initLength; k > j; k--) {
if (nodeArray[k - 1].left != -1) {
nodeArray[nodeArray[k - 1].left].parent = k;
nodeArray[nodeArray[k - 1].right].parent = k;
}
if ((k - 1) == nodeArray[nodeArray[k - 1].parent].left) {
nodeArray[nodeArray[k - 1].parent].left = k;
} else if ((k - 1) == nodeArray[nodeArray[k - 1].parent].right) {
nodeArray[nodeArray[k - 1].parent].right = k;
}
nodeArray[k] = nodeArray[k - 1];
}
if (j < nodeArray.length) {
nodeArray[j] = parent;
x.parent = j;
y.parent = j;
}
initLength++;
i += 2;
}
for (int i = 0; i < nodeArray.length; i++) {
System.out.println(i + "->" + nodeArray[i]);
}
Node root = nodeArray[nodeArray.length - 1];
List<String> codeStack = new ArrayList<String>();
List<Node> nodeStack = new ArrayList<Node>();
for (;;) {
if (root.left != -1) {
nodeStack.add(root);
root = nodeArray[root.left];
codeStack.add("0");
} else {
String code01 = "";
for (int i = 0; i < codeStack.size(); i++)
code01 += codeStack.get(i);
map.put(root.key, code01);
if (root == nodeArray[nodeArray[root.parent].left]) {
codeStack.set(codeStack.size() - 1, "1");
root = nodeArray[nodeArray[root.parent].right];
} else {
while (!root.equals(nodeArray[nodeArray.length - 1])
&& root == nodeArray[nodeArray[root.parent].right]) {
root = nodeStack.remove(nodeStack.size() - 1);
codeStack.remove(codeStack.size() - 1);
}
if (root.equals(nodeArray[nodeArray.length - 1]))
break;
codeStack.set(codeStack.size() - 1, "1");
root = nodeArray[nodeArray[root.parent].right];
}
}
}
System.out.println(map);
}
public static class Node {
public char key;
public int weight;
public int parent;
public int right;
public int left;
public Node(char key, int weight, int parent, int right, int left) {
super();
this.key = key;
this.weight = weight;
this.parent = parent;
this.right = right;
this.left = left;
}
@Override
public String toString() {
return "Node [key=" + key + ", weight=" + weight + ", parent=" + parent + ", right=" + right + ", left="
+ left + "]";
}
public Node() {
}
public Node(char key, int weight, int right, int left) {
super();
this.key = key;
this.weight = weight;
this.right = right;
this.left = left;
}
public Node(int weight, int right, int left) {
super();
this.weight = weight;
this.right = right;
this.left = left;
}
public Node(char key, int weight) {
this.key = key;
this.weight = weight;
}
}
}
java实现Huffman树
最新推荐文章于 2022-09-26 23:56:21 发布