Cómic: ¿Qué es el "árbol de Huffman"?

Autor | 小 灰

Fuente | Programador Xiaohui (ID: chengxuyuanxiaohui)

————— Al día siguiente —————

————————————

Concepto 1: ¿Qué es un camino?

En un árbol, todos los nodos que pasan de un nodo a otro se llaman la ruta entre los dos nodos.

En el árbol binario anterior, la ruta del nodo raíz A al nodo hoja H es A, B, D, H.

Concepto 2: ¿Cuál es la longitud del camino?

En un árbol, el número de "bordes" atravesados ​​de un nodo a otro se denomina longitud de la ruta entre los dos nodos.

Todavía utilizando el ejemplo del árbol binario en este momento, desde el nodo raíz A hasta el nodo hoja H, se pasan un total de 3 bordes, por lo que la longitud de la ruta es 3.

Concepto 3: ¿Cuál es la longitud de ruta ponderada de un nodo?

Cada nodo del árbol puede tener su propio "peso" (Peso), el peso puede jugar diferentes roles en diferentes algoritmos.

La longitud de ruta ponderada de un nodo se refiere al producto de la longitud de ruta desde el nodo raíz del árbol hasta el nodo y el peso del nodo.

Suponga que el peso del nodo H es 3, y la longitud de la ruta desde el nodo raíz al nodo H también es 3. Por lo tanto, la longitud de la ruta ponderada del nodo H es 3 X 3 = 9.

Concepto 4: ¿Cuál es la longitud del camino ponderado del árbol?

En un árbol, la suma de las longitudes de ruta ponderadas de todos los nodos de hoja se denomina longitud de ruta ponderada del árbol, y también se conoce como WPL para abreviar.

Todavía tomando este árbol binario como ejemplo, la longitud de la ruta del árbol es 3X3 + 6X3 + 1X2 + 4X2 + 8X2 = 53.

El árbol Huffman fue inventado por el Dr. Huffman del Instituto de Tecnología de Massachusetts en 1952. ¿Qué tipo de árbol es este?

Acabamos de aprender la longitud de la ruta ponderada (WPL) del árbol, y el árbol Huffman es un árbol binario con la longitud de ruta ponderada más pequeña bajo la condición de nodos y pesos de las hojas, también conocido como el árbol binario óptimo .

Por ejemplo, dados los nodos de hoja con pesos de 1, 3, 4, 6, 8 respectivamente, ¿qué tipo de árbol binario debemos construir para garantizar que la longitud de la ruta ponderada sea mínima?

En principio, debemos mantener los nodos de hoja con pesos pequeños lejos de las raíces, y los nodos de hoja con pesos grandes cerca de las raíces.

El árbol en el lado izquierdo de la figura a continuación es un árbol Huffman con un WPL de 46, que es menor que 53 en el ejemplo anterior:

Cabe señalar que puede haber más de un árbol Huffman formado por los mismos nodos foliares. Los siguientes árboles son todos árboles Huffman:

Supongamos que hay 6 nodos de hoja y los pesos son 2, 3, 7, 9, 18, 25. En orden. ¿Cómo construir un árbol Huffman, es decir, el árbol con la longitud de camino ponderada más pequeña?

Paso 1: construye el bosque

Tratamos cada nodo hoja como un árbol independiente (un árbol con solo nodos raíz), formando así un bosque:

En la imagen de arriba, el bosque de nodos de hoja está a la derecha, y una cola auxiliar está a la izquierda. Todos los nodos de hoja se almacenan en orden descendente de peso. En cuanto al papel de las colas auxiliares, lo veremos más adelante.

Paso 2: Seleccione los dos nodos con el peso actual más pequeño para generar un nuevo nodo padre

Con la ayuda de la cola auxiliar, podemos encontrar los nodos 2 y 3 con el peso más pequeño y generar un nuevo nodo padre basado en estos dos nodos. El peso del nodo padre es la suma de los pesos de estos dos nodos:

Paso 3: elimine los dos nodos más pequeños seleccionados en el paso anterior de la cola y agregue el nuevo nodo principal a la cola

Es decir, elimine 2 y 3 de la cola, inserte 5 y aún mantenga el orden ascendente de la cola:

Paso 4: Seleccione los dos nodos con el peso actual más pequeño para generar un nuevo nodo padre.

Esta es una operación repetida para el segundo paso. Los nodos con los pesos más pequeños en la cola actual son 5 y 7, y los pesos para generar nuevos nodos principales son 5 + 7 = 12:

Paso 5: elimine los dos nodos más pequeños seleccionados en el paso anterior de la cola y agregue el nuevo nodo principal a la cola.

Esta es la operación repetida del tercer paso, que consiste en eliminar 5 y 7 de la cola, insertar 12 y aún mantener el orden ascendente de la cola:

Paso 6: Seleccione los dos nodos con el peso actual más pequeño para generar un nuevo nodo padre.

Esta es una operación repetida para el segundo paso. Los nodos con el peso más pequeño en la cola actual son 9 y 12, y el peso del nuevo nodo padre es 9 + 12 = 21:

Paso 7: elimine los dos nodos más pequeños seleccionados en el paso anterior de la cola y agregue el nuevo nodo principal a la cola.

Esta es una operación repetida para el tercer paso, que consiste en eliminar 9 y 12 de la cola, insertar 21 y aún mantener el orden ascendente de la cola:

Paso 8: Seleccione los dos nodos con el peso actual más pequeño para generar un nuevo nodo padre.

Esta es una operación repetida para el segundo paso. Los nodos con el peso más pequeño en la cola actual son 18 y 21, y el peso del nuevo nodo padre es 18 + 21 = 39:

Paso 9: elimine los dos nodos más pequeños seleccionados en el paso anterior de la cola y agregue el nuevo nodo principal a la cola.

Esta es una operación repetida para el tercer paso, que consiste en eliminar 18 y 21 de la cola, insertar 39 y mantener el orden ascendente de la cola:

Paso 10: Seleccione los dos nodos con el peso actual más pequeño para generar un nuevo nodo padre.

Esta es una operación repetida para el segundo paso. Los nodos con los pesos más pequeños en la cola actual son 25 y 39, y los pesos para generar nuevos nodos principales son 25 + 39 = 64:

Paso 11: elimine los dos nodos más pequeños seleccionados en el paso anterior de la cola y agregue el nuevo nodo principal a la cola

Esta es la operación repetida para el tercer paso, que es eliminar 25 y 39 de la cola e insertar 64:

En este momento, solo hay un nodo en la cola, lo que indica que todo el bosque se ha fusionado en un árbol, y este árbol es el árbol Huffman que queremos:

private Node root;
private Node[] nodes;

//构建哈夫曼树
public void createHuffman(int[] weights) {

//优先队列,用于辅助构建哈夫曼树

Queue<Node> nodeQueue = new PriorityQueue<>();
    nodes = new Node[weights.length];


//构建森林,初始化nodes数组

for(int i=0; i<weights.length; i++){
        nodes[i] = new Node(weights[i]);
        nodeQueue.add(nodes[i]);

}


//主循环,当结点队列只剩一个结点时结束

while (nodeQueue.size() > 1) {

//从结点队列选择权值最小的两个结点

Node left = nodeQueue.poll();

Node right = nodeQueue.poll();

//创建新结点作为两结点的父节点

Node parent = new Node(left.weight + right.weight, left, right);
        nodeQueue.add(parent);

}
    root = nodeQueue.poll();
}

//按照前序遍历输出
public void output(Node head) {

if(head == null){

return;

}

System.out.println(head.weight);
    output(head.lChild);
    output(head.rChild);
}

public static class Node implements Comparable<Node>{

int weight;

Node lChild;

Node rChild;


public Node(int weight) {

this.weight = weight;

}


public Node(int weight, Node lChild, Node rChild) {

this.weight = weight;

this.lChild = lChild;

this.rChild = rChild;

}


@Override

public int compareTo(Node o) {

return new Integer(this.weight).compareTo(new Integer(o.weight));

}
}

public static void main(String[] args) {

int[] weights = {2,3,7,9,18,25};

HuffmanTree huffmanTree = new HuffmanTree();
    huffmanTree.createHuffman(weights);
    huffmanTree.output(huffmanTree.root);
}

En este código, para garantizar que los nodos en la cola de nodos estén siempre dispuestos en orden ascendente de peso, utilizamos la cola de prioridad PriorityQueue.

Al mismo tiempo, el Nodo de clase interna estático necesita implementar la interfaz de comparación y reescribir el método compareTo para garantizar que el objeto Node se compare de acuerdo con el peso al ingresar a la cola.


【FINAL】

Más recomendaciones interesantes

☞El magnate 360 ​​que fue bloqueado por Zhou Hongyi a través de la red: ¡trabajadores de base a los cientos de millones de contraataques de 36 años!

2020 En 2020, 5 lenguajes de programación que vale la pena aprender en ciberseguridad

☞ ¡ 10x HD no cuesta! Renderizado SVG de selección final de cebada

¿Microsoft adquirió una compañía para una persona? ¡Descifra programas de Sony, escribe novelas de hackers y mira su dura vida de programa!

Plantilla de proyecto de aprendizaje automático: 6 pasos básicos del proyecto ML

☞IBM, Microsoft, Apple, Google, Samsung ... ¡Estos gigantes de la tecnología en la cadena de bloques ya han hecho tantas cosas!

Resumen de programadores senior: te contaré las 6 formas de analizar el proceso de Linux

El bienestar de hoy: si deja un comentario en el área de comentarios, puede obtener un boleto para la transmisión en vivo de la "Conferencia de diez mil desarrolladores de inteligencia artificial de 2020" por un valor de 299 yuanes . Ven y mueve tu dedo y escribe lo que quieres decir.

Haga clic para leer el texto original, ¡maravilloso para continuar!

Cada "observación" que pides, me lo tomo en serio

Artículos originales publicados en 1940 · 40 mil likes + · 18.13 millones de visitas

Supongo que te gusta

Origin blog.csdn.net/csdnnews/article/details/105424420
Recomendado
Clasificación