Reproduzido de: gráficos detalhados JAVA Huffman árvores
O conceito :
Dado n pesos como os n nós de folha , uma configuração árvore binária, se o comprimento do caminho ponderada da árvore atinja um valor mínimo, uma árvore binária tal é chamado ideal árvore binária, também conhecido como Huffman árvore (Huffman árvore). árvore de Huffman é o mais curto árvore ponderada comprimento do percurso, quanto maior for o peso a partir do nó de raiz mais perto.
A sua construção é simples, sequencialmente selecionando o menor peso na parte inferior no nó da árvore, o novo nó irá constituir um mínimo de duas conexões, de notar que os pesos que constituem o novo nó deve ser igual a dois valores de nó direita e para trás, em seguida, colocado no novo nó precisamos para constituir um nó da árvore continua a classificar árvore Huffman construídos esses nós que todas as informações são armazenadas são nós folha diante.
Exemplos:
Há uma string: aaaaaaaaaabbbbbaaaaaccccccccddddddfff
O primeiro passo, vamos contar o número de vezes que cada personagem aparece, chamado o peso do personagem. um: 15, b: 5, C: 8, d: 6, f: 3.
O segundo passo, para encontrar lá um peso mínimo de dois personagens, B5 e F3, a construção de nó.
F3, em seguida, removido e b5, agora A15, c8, d6, fb8.
Um terceiro passo, o segundo passo é repetido até que apenas um nó construído.
É dfb14, a15, c8.
finalmente,
ok, então nós Huffman árvore é construída completa.
( Nota: a árvore original é construído aqui para começar a construir a partir da direita, como mostrado na dieta normal, mas deve começar a construir-se a partir da esquerda e do fundo, código Java é apresentado a seguir, os resultados da saída final é seguir o princípio. travessia)
package com.gxu.dawnlab_algorithm7;
import java.util.ArrayList;
import com.gxu.dawnlab_algorithm3.PrintBinaryTree.Node;
/**
* 哈夫曼数的实现
* @author junbin
*
* 2019年7月11日
*/
public class Huffman {
public static class Node{
public String data;// 节点的数据
public int count;// 节点的权值
public Node lChild;
public Node rChild;
public Node() {
}
public Node(String data, int count) {
this.data = data;
this.count = count;
}
public Node(int count, Node lChild, Node rChild) {
this.count = count;
this.lChild = lChild;
this.rChild = rChild;
}
public Node(String data, int count, Node lChild, Node rChild) {
this.data = data;
this.count = count;
this.lChild = lChild;
this.rChild = rChild;
}
}
private String str;// 最初用于压缩的字符串
private String newStr = "";// 哈夫曼编码连接成的字符串
private Node root;// 哈夫曼二叉树的根节点
private boolean flag;// 最新的字符是否已经存在的标签
private ArrayList<String> charList;// 存储不同字符的队列:相同字符存在同一位置
private ArrayList<Node> NodeList;// 存储节点的队列
/**
* 构建哈夫曼树
*
* @param str
*/
public void creatHfmTree(String str) {
this.str = str;
charList = new ArrayList<String>();
NodeList = new ArrayList<Node>();
// 1.统计字符串中字符以及字符的出现次数
// 基本思想是将一段无序的字符串如ababccdebed放到charList里,分别为aa,bbb,cc,dd,ee
// 并且列表中字符串的长度就是对应的权值
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i); // 从给定的字符串中取出字符
flag = true;
for (int j = 0; j < charList.size(); j++) {
if (charList.get(j).charAt(0) == ch) {// 如果找到了同一字符
String s = charList.get(j) + ch;
charList.set(j, s);
flag = false;
break;
}
}
if (flag) {
charList.add(charList.size(), ch + "");
}
}
// 2.根据第一步的结构,创建节点
for (int i = 0; i < charList.size(); i++) {
String data = charList.get(i).charAt(0) + ""; // 获取charList中每段字符串的首个字符
int count = charList.get(i).length(); // 列表中字符串的长度就是对应的权值
Node node = new Node(data, count); // 创建节点对象
NodeList.add(i, node); // 加入到节点队列
}
// 3.对节点权值升序排序
Sort(NodeList);
while (NodeList.size() > 1) {// 当节点数目大于一时
// 4.取出权值最小的两个节点,生成一个新的父节点
// 5.删除权值最小的两个节点,将父节点存放到列表中
Node left = NodeList.remove(0);
Node right = NodeList.remove(0);
int parentWeight = left.count + right.count;// 父节点权值等于子节点权值之和
Node parent = new Node(parentWeight, left, right);
NodeList.add(0, parent); // 将父节点置于首位
}
// 6.重复第四五步,就是那个while循环
// 7.将最后的一个节点赋给根节点
root = NodeList.get(0);
output(root);
}
/**
* 升序排序
*
* @param nodelist
*/
public void Sort(ArrayList<Node> nodelist) {
for (int i = 0; i < nodelist.size() - 1; i++) {
for (int j = i + 1; j < nodelist.size(); j++) {
Node temp;
if (nodelist.get(i).count > nodelist.get(j).count) {
temp = nodelist.get(i);
nodelist.set(i, nodelist.get(j));
nodelist.set(j, temp);
}
}
}
}
/**
* 先序遍历
*
* @param node
* 节点
*/
public void output(Node head) {
if(head == null){
return;
}
System.out.print(head.count + " ");
output(head.lChild);
output(head.rChild);
}
public void output() {
output(root);
}
public static void main(String[] args) {
Huffman huff = new Huffman();//创建哈弗曼对象
huff.creatHfmTree("aaaaaaaaaabbbbbaaaaaccccccccddddddfff");//构造树
}
}
Preorder saída do resultado travessia é: 3722148356815.