Implementación min-heap del árbol de Huffman

árbol de huffman

definición

Longitud de ruta ponderada (WPL): suponiendo que el árbol binario tiene n nodos de hoja, cada nodo de hoja tiene un peso W k , y la longitud desde el nodo raíz hasta cada nodo de hoja es L k , entonces la longitud de cada nodo de hoja La suma de longitudes de ruta ponderadas es: WPL = ∑ k = 1 n W k L k WPL=\sum_{k=1}^{n}W_kL_kW P L=k = 1nWkLk

características

  1. No hay nodos con grado 1
  2. Un árbol de Huffman con n nodos de hoja tiene un total de 2n-1 nodos
  3. Los subárboles izquierdo y derecho de cualquier nodo que no sea hoja del árbol de Huffman siguen siendo árboles de Huffman después del intercambio.
  4. Para el mismo conjunto de pesos, existen diferentes árboles de Huffman

diagrama

inicial

1
3
5
8

primera fusion

1
3
4
5
8

segunda fusión

1
3
4
5
8
9

tercera fusión

1
3
4
5
8
9
17

plantilla

De acuerdo con los n pesos dados, construya n árboles binarios con solo nodos raíz. A través del montón mínimo, seleccione dos árboles con el peso más pequeño del nodo raíz como los subárboles izquierdo y derecho cada vez, construya un nuevo árbol binario e insértelo en el montón mínimo. Repita los pasos anteriores hasta que solo quede un árbol, que es el árbol de Huffman.

#include <iostream>
using namespace std;

#define MaxSize 1000
int A[] = {
    
    1, 3, 5, 8};
int A_length = 4;

struct TreeNode
{
    
    
    int weight;
    TreeNode *left;
    TreeNode *right;
};
struct MinHeap
{
    
    
    TreeNode **data; //这是一个数组,每个元素的类型为(TreeNode*),是指向某个哈夫曼树的指针
    int size;
    int capacity;
};

MinHeap *CreateHeap();                   // 初始化堆
TreeNode *CreateHT();                    // 初始化哈夫曼树
TreeNode *Delete(MinHeap *H);            // 删除最小堆元素
void Insert(MinHeap *H, TreeNode *Huff); // 插入最小堆元素
void PreOrderTraversal(TreeNode *Huff);  // 先序遍历
void BuildMinHeap(MinHeap *H);           // 建堆
TreeNode *Huffman(MinHeap *H);           // 哈夫曼树的构建

int main()
{
    
    
    MinHeap *H;
    TreeNode *Huff;
    H = CreateHeap();
    Huff = Huffman(H);
    PreOrderTraversal(Huff);
    system("pause");
    return 0;
}

// 初始化堆
MinHeap *CreateHeap()
{
    
    
    MinHeap *H;
    H = new MinHeap;
    H->data = new TreeNode *[MaxSize + 1]; // 每个元素的类型为(TreeNode*)
    H->capacity = MaxSize;
    H->size = 0;
    // 给堆设置哨兵,哨兵要小于堆内所有值
    TreeNode *Huff;
    Huff = CreateHT();
    Huff->weight = INT_MIN;
    H->data[0] = Huff;
    return H;
}

// 初始化哈夫曼树
TreeNode *CreateHT()
{
    
    
    TreeNode *Huff;
    Huff = new TreeNode;
    Huff->weight = 0;
    Huff->left = NULL;
    Huff->right = NULL;
    return Huff;
}

// 插入最小堆元素(哈夫曼树)
void Insert(MinHeap *H, TreeNode *Huff)
{
    
    
    int weight = Huff->weight;
    int i = ++H->size;
    for (; H->data[i / 2]->weight > weight; i /= 2)
    {
    
    
        H->data[i] = H->data[i / 2];
    }
    H->data[i] = Huff;
}

// 删除最小堆元素
TreeNode *Delete(MinHeap *H)
{
    
    
    int parent, child;
    TreeNode *T = H->data[1];
    TreeNode *tmp = H->data[H->size--];
    for (parent = 1; parent * 2 <= H->size; parent = child)
    {
    
    
        child = 2 * parent;
        if ((child != H->size) && (H->data[child + 1]->weight < H->data[child]->weight))
            child++;
        if (H->data[child]->weight >= tmp->weight)
            break;
        else
            H->data[parent] = H->data[child];
    }
    H->data[parent] = tmp;
    return T;
}

// 建堆
void BuildMinHeap(MinHeap *H)
{
    
    
    TreeNode *Huff;
    for (int i = 0; i < A_length; i++)
    {
    
    
        Huff = CreateHT();
        Huff->weight = A[i];
        Insert(H, Huff);
    }
}

void PreOrderTraversal(TreeNode *Huff)
{
    
    
    if (Huff)
    {
    
    
        cout << Huff->weight << " ";
        PreOrderTraversal(Huff->left);
        PreOrderTraversal(Huff->right);
    }
}

//构建哈夫曼树
TreeNode *Huffman(MinHeap *H)
{
    
    
    TreeNode *T;
    BuildMinHeap(H);
    int times = H->size;
    // 做times-1次合并
    for (int i = 1; i < times; i++)
    {
    
    
        T = new TreeNode;
        T->left = Delete(H);
        T->right = Delete(H);
        T->weight = T->left->weight + T->right->weight;
        Insert(H, T);
    }
    T = Delete(H);
    return T;
}

Supongo que te gusta

Origin blog.csdn.net/leoabcd12/article/details/117821568
Recomendado
Clasificación