哈夫曼树的最小堆实现

简介: 哈夫曼树的最小堆实现

哈夫曼树


定义

带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子节点带有权值Wk,从根结点到每个叶子节点的长度为Lk,则每个叶子结点的带权路径长度之和就是:

WPL=∑ k=1nW k L k


特点

1.没有度为1的结点

2.n个叶子结点的哈夫曼树共有2n-1个结点

3.哈夫曼树的任意非叶子结点的左右子树交换后仍是哈夫曼树

4.同一组权值,存在不同构的哈夫曼树


图解

初始

image.png

第一次合并

image.png

第二次合并

image.png

第三次合并

image.png


模板

根据给定的n个权值,构造n棵只有根结点的二叉树。通过最小堆每次选取两棵根结点权值最小的树作为左右子树,构造一棵新的二叉树,并将其插入最小堆中。重复上述步骤,直到只有一棵树为止,这棵树就是哈夫曼树。

#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;
}
目录
相关文章
|
算法 网络协议
生成树协议:网络稳定的守护者
【4月更文挑战第22天】
246 0
|
Linux 网络虚拟化 虚拟化
Linux虚拟网络设备深度解析:使用场景、分类与开发者指南
Linux虚拟网络设备支撑着各种复杂的网络需求和配置,从基础的网络桥接到高级的网络隔离和加密🔐。以下是对主要Linux虚拟网络设备的介绍、它们的作用以及适用场景的概览,同时提出了一种合理的分类,并指出应用开发人员应该着重掌握的设备。
Linux虚拟网络设备深度解析:使用场景、分类与开发者指南
|
监控 安全 算法
uwb人员定位系统:人员轨迹实时定位
vuwb人员定位系统:人员轨迹实时定位
750 0
uwb人员定位系统:人员轨迹实时定位
|
C语言
【C语言基础考研向】05 scanf读取标准输入超详解
本文详细解析了C语言中`scanf`函数的工作原理及常见问题。首先介绍了`scanf`如何处理标准输入,并通过示例说明了为何有时会出现阻塞现象及其解决办法。接着探讨了当输入包含多种数据类型时,特别是字符型数据的处理方式,强调了格式控制的重要性,并给出了正确的输入格式示例。通过正确配置,可以避免因空格和换行符导致的问题,确保数据准确读取。
397 10
|
机器学习/深度学习 供应链 算法
区块链与机器学习:未来科技交叉口的深度洞察
随着科技进步,区块链与机器学习成为焦点技术。区块链以去中心化和安全性革新金融、供应链等领域;机器学习通过算法促进各行业创新。二者结合,区块链提供可靠数据支持机器学习,而机器学习优化区块链性能。应用场景包括金融信用评估、供应链管理、医疗健康及智能合约等。面对数据隐私保护、算法优化等挑战,需跨学科合作并完善政策法规。展望未来,技术突破、产业应用拓展及跨学科人才培养将推动这一领域向前发展。
892 3
|
测试技术 数据安全/隐私保护 Python
大麦网抢票攻略:使用Python Selenium实现
大麦网抢票攻略:使用Python Selenium实现
|
Oracle 关系型数据库 Unix
关系型数据库Oracle设置环境变量:
【7月更文挑战第22天】
1335 4
|
存储 前端开发 数据安全/隐私保护
Base64详解:从编码原理到应用实践
Base64详解:从编码原理到应用实践
【数字IC手撕代码】Verilog小数分频|题目|原理|设计|仿真
【数字IC手撕代码】Verilog小数分频|题目|原理|设计|仿真
【数字IC手撕代码】Verilog小数分频|题目|原理|设计|仿真
|
安全 数据库 网络虚拟化
计算机网络:思科实验【4-生成树协议STP及虚拟局域网VLAN】
计算机网络:思科实验【4-生成树协议STP及虚拟局域网VLAN】