C++实现哈夫曼树算法

C++实现哈夫曼树算法攻略

哈夫曼树,又称最优二叉树,是一种带权路径长度最短的二叉树。它常用于数据压缩和编码的算法中。

1. 哈夫曼树的定义

哈夫曼树是一种满足以下属性的二叉树:

  1. 树中每个叶子节点都对应一个权值;
  2. 树中每个非叶子节点的权值是其左右子树中权值之和;
  3. 树的带权路径长度最小。

2. 哈夫曼编码的实现

哈夫曼编码是一种前缀编码,它把每个不同符号对应到一段等长的编码,使得解码时不会有歧义。编码的长度与该符号在文本中出现的频率有关。

3. 具体实现步骤

3.1 定义哈夫曼树节点结构体

定义一个节点结构体来存储哈夫曼树的信息,包括权值、左右子节点以及哈夫曼编码等。

struct HuffmanNode {
    int weight;             // 权值
    int parent, left, right;// 双亲链及左右孩子链
    string code;            // 结点的哈夫曼编码
};

3.2 定义比较器

定义比较器用于对哈夫曼树节点进行排序,保证构建哈夫曼树时权值较小的节点排在前面。

struct cmp {
    bool operator()(const HuffmanNode &a, const HuffmanNode &b) {
        return a.weight > b.weight;
    }
};

3.3 生成哈夫曼树

输入每个节点的权值,按权值从小到大排序后初始化哈夫曼树的n个叶子节点,再根据哈夫曼树的定义合并这些节点,最终生成完整的哈夫曼树。

priority_queue<HuffmanNode, vector<HuffmanNode>, cmp> huff_q;     // 优先队列
int n, m;

void init() {
    for (int i = 1; i <= n; i++) {
        cin >> node[i].weight;
        huff_q.push(node[i]);
    }
    m = (n << 1) - 1;   // 计算哈夫曼树节点总数
    for (int i = n + 1; i <= m; i++) {
        int p1 = huff_q.top().weight;
        huff_q.pop();
        int p2 = huff_q.top().weight;
        huff_q.pop();
        node[i].left = p1;
        node[i].right = p2;
        node[i].weight = p1 + p2;
        huff_q.push(node[i]);
    }
}

3.4 生成哈夫曼编码

对于哈夫曼树的每个叶子节点,由于左孩子编码为0,右孩子编码为1,我们可从叶子节点出发向根节点反向求出每个节点的哈夫曼编码。

void getHuffmanCode(int n) {
    int len = node[n].code.length();
    if (len) {
        return;
    }
    if (!node[n].parent) {
        return;
    }
    if (node[node[n].parent].left == n) {
        getHuffmanCode(node[n].parent);
        node[n].code = node[node[n].parent].code + '0';
    } else {
        getHuffmanCode(node[n].parent);
        node[n].code = node[node[n].parent].code + '1';
    }
}

3.5 示例说明

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    init();
    for (int i = 1; i <= n; i++) {
        getHuffmanCode(i);
    }
    for (int i = 1; i <= n; i++) {
        cout << node[i].weight << " " << node[i].code << "\n";
    }
    return 0;
}

输入:

5
5 2 4 7 10

输出:

5 00001
2 100
4 001
7 01
10 0000

另一个示例:当输入为12 7 8 10时,得到的哈夫曼编码为:

12 0
7 11
8 100
10 101

4. 总结

哈夫曼树是一种非常有用的数据结构,它能够快速生成最优编码方案。本文中详细讲解了哈夫曼树算法的实现,包括定义节点结构体、优先队列的使用、哈夫曼树的生成以及哈夫曼编码的计算过程等。通过以上步骤,我们可以轻松实现哈夫曼树算法,并得到正确的编码结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++实现哈夫曼树算法 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • 利用C语言实现2048小游戏的方法

    利用C语言实现2048小游戏的方法 项目描述: 2048是一种非常受欢迎的数字连线游戏。玩家需要通过滑动数字来合并相同的数字,得到更高的分数。在这个项目中,我们将展示如何使用C语言实现2048小游戏的完整方法。 实现步骤: 步骤一:创建格子矩阵 2048小游戏是一个4×4的矩阵,我们可以使用一个二维数组来表示这个矩阵。代码可以使用如下的方式进行: int m…

    C 2023年5月23日
    00
  • JS使用JSON作为参数实例分析

    下面是关于”JS使用JSON作为参数实例分析”的详细攻略: 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人们阅读和编写,并且易于机器解析和生成。它是基于JavaScript语言的一个子集,所以在JS中使用JSON是非常方便的事情。 JSON语法 JSON语法是JavaScript语法的子集。…

    C 2023年5月23日
    00
  • 荣耀畅玩8C手机做工如何?荣耀畅玩8C手机拆机全过程评测

    荣耀畅玩8C手机做工评测 1. 外观设计 荣耀畅玩8C手机的外观设计非常简洁,采用了流行的刘海屏设计。机身采用金属材质,整体质感比较好。机身厚度较薄,手感舒适。机身背面还配有指纹识别器,方便快捷。 2. 屏幕 荣耀畅玩8C手机采用了6.26英寸的高清显示屏,分辨率达到了720 x 1520像素。屏幕质量很不错,色彩鲜艳度和亮度都很高。观看视频、浏览图片时非常…

    C 2023年5月23日
    00
  • VS2015中怎么创建C语言文件?

    首先,打开Visual Studio 2015,选择新建项目(New Project)。 然后,在弹出的新项目窗口中,选择Visual C++,在Visual C++中选择Console Application(控制台应用程序)。 在控制台应用程序设置中,我们需要选择C++语言核心选项,因为C语言是C++的超集。 在接下来的窗口中,我们需要设置项目的名称和存…

    C 2023年5月23日
    00
  • QT基于TCP实现网络聊天室程序

    首先我们需要准备QT的开发环境,并且熟悉QT的基本开发流程。在此不再赘述。 创建QT项目 首先需要创建一个QT项目,选择一个QT GUI Application即可。在创建过程中,选择需要包含网络模块。 添加TCP服务器 我们需要添加一个TCP服务器来实现网络聊天室。在创建TCP服务器时,需要指定服务器绑定的IP地址和端口号。以下是示例代码: QTcpSer…

    C 2023年5月30日
    00
  • c++显式类型转换示例详解

    C++ 显式类型转换示例详解 什么是显式类型转换 在C++中,有时候我们需要将一种数据类型(例如字符串)转换为另一种数据类型(例如数字)。这就需要使用类型转换操作符。 C++中的类型转换分为两种,一种是隐式类型转换,另一种是显式类型转换。其中隐式类型转换由编译器自动完成,而显式类型转换需要程序员手动调用类型转换操作符进行转换。 显式类型转换的语法 C++支持…

    C 2023年5月24日
    00
  • shell 通过makefile传参给c语言的实现示例

    下面是详细讲解 shell 通过 makefile 传参给 C 语言的实现示例的完整攻略: 1. 确定传参的方式 命令行参数:在程序执行时,可以通过命令行传入参数,使用 main() 函数中的 argc 和 argv 进行接收; 环境变量:通过设置和获取环境变量,来传递参数; 读取配置文件:在程序运行前读取配置文件,将需要的参数传入程序中; Makefile…

    C 2023年5月23日
    00
  • vscode配置远程开发环境并远程调试运行C++代码的教程

    下面我将为您详细讲解如何使用 VSCode 配置远程开发环境并远程调试运行 C++ 代码。 准备工作 在开始之前,我们需要准备以下工具和环境: VSCode Remote Development 插件 SSH 客户端程序 远程服务器 其中,Remote Development 是一个专门提供远程开发功能的 VSCode 插件,它可以让我们在本地使用 VSCo…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部