哈夫曼算法详细讲解(算法+源码)

博主介绍:✌全网粉丝喜爱+、前后端领域优质创作者、本质互联网精神、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战✌有需要可以联系作者我哦!

🍅文末获取源码联系🍅

👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟

 

目录

一、哈夫曼算法

二、哈夫曼算法(完整C语言算法)

三、算法优缺点总结

大家点赞、收藏、关注、评论啦 !

谢谢哦!如果不懂,欢迎大家下方讨论学习哦。


一、哈夫曼算法

哈夫曼编码是一种可变字长编码(Variable Length Coding)的一种方法,通过根据不同字符出现的频率来构建一颗具有最小编码长度的二叉树。该树的构建和遍历规则使得出现频率高的字符获得较短的编码,而出现频率低的字符获得较长的编码,从而达到对数据进行高效压缩的目的。

以下是哈夫曼编码的基本步骤:

1. 统计字符频率:遍历输入的字符流,统计每个字符出现的频率。

2. 构建哈夫曼树: 将每个字符及其频率作为叶子节点,构建一颗二叉树。在每一步中,选择两个最小频率的节点合并,直到只剩下一个根节点。

3. 生成编码:*通过遍历哈夫曼树,从根节点到每个叶子节点的路径上赋予0或1的编码。叶子节点上的编码即为对应字符的哈夫曼编码。

4. 生成编码表: 将每个字符及其对应的哈夫曼编码存储在一个编码表中,用于编码和解码。

5. 数据压缩:*使用生成的哈夫曼编码对原始数据进行编码,从而实现数据的压缩。

6. 数据解压: 利用编码表对压缩后的数据进行解码,还原为原始数据。

哈夫曼编码的优点在于对频率较高的字符进行了有效的压缩,使得整体的编码长度较短,从而节省了存储空间。这使得哈夫曼编码在数据传输和存储中得到广泛应用,特别是在无损数据压缩领域。

二、哈夫曼算法(完整C语言算法)

#include<stdio.h>
#include<malloc.h>
#include <iostream>

//定义初始化
#define Max 20
#define MaxValue 1000
using namespace std;
typedef struct huffNode
{
    char ch;
    int weight;  //赋以权重 
    int lChild;  //左孩子 
    int rChild;  //右孩子 
    int parent;  //父节点 
    char hCode[Max];   //记录哈夫曼编码 
}huffman;
void init(huffman *huffmanTree,int *w,char *z,int n)
{
    int i;
    //for(i=0;i<2*n-1;i++)
    //    huffmanTree[i]=(huffman *)malloc(sizeof(huffman));

    for(i=0;i<2*n-1;i++)
    {
        huffmanTree[i].ch=z[i];
        huffmanTree[i].weight=w[i];
        huffmanTree[i].parent=-1;
        huffmanTree[i].lChild=-1;
        huffmanTree[i].rChild=-1;
    }
}

void setHuffmanTree(huffman *huffmanTree,int n)
{
    int m,m1,m2,x1,x2,i,j;
    m=2*n-1;
    for(i=n;i<m;++i)
    {
        m1=m2=MaxValue;
        x1=x2=0;
        for(j=0;j<i;++j)
        {
            if(huffmanTree[j].parent==-1&&huffmanTree[j].weight<m1)
            {
                m2=m1;x2=x1;m1=huffmanTree[j].weight;x1=j;
            }
            else if (huffmanTree[j].parent==-1&&huffmanTree[j].weight<m2)
            {    m2=huffmanTree[j].weight;x2=j;
            }
        }
        huffmanTree[x1].parent=i;
        huffmanTree[x2].parent=i;
        huffmanTree[i].lChild=x1;
        huffmanTree[i].rChild=x2;
        huffmanTree[i].weight=m1+m2;
    }
}
void huffmanTreeCode(huffman *huffmanTree,int n)
{
    char hc[Max];
    int hcLen;
    int i,j,k,parent,p;
    for(i=0;i<n;i++)
    {
        hcLen=0;
        parent=huffmanTree[i].parent;//待编码字符的双亲结点下标
        p=i;
        while(parent!=-1)//未到达根结点
        {
            if(huffmanTree[parent].lChild==p)//是左孩子
                hc[hcLen]='0',hcLen++;
            else if(huffmanTree[parent].rChild==p)//是右孩子
                hc[hcLen]='1',hcLen++;
                p=parent;
                parent=huffmanTree[parent].parent;//继续向根结点查找
    }
    for(j=0,k=hcLen-1;j<hcLen;j++,k--)//将编码写入相应字符数组
        huffmanTree[i].hCode[j]=hc[k];
        huffmanTree[i].hCode[j]='\0';//加上字符串结束符
    }

    return;
}
int main()
{
    int n,i;

    char z,*Z;
    int w,W[Max];
    huffman huffmanTree[Max];
    
    printf("请输入叶子个数:\n");
    scanf("%d",&n);
   //W=(int *)malloc(n*sizeof(int));
    Z=(char *)malloc(n*sizeof(char));
    printf("请输入%d个字符和权值。\n",n);
    for(i=0;i<n;i++)
    {
        printf("请输入第%d个字符:\n",i+1);
        //scanf("%c",&z);
        cin>>z;
        Z[i]=z;
        printf("请输入第%d个字符的权:\n",i+1);
        //scanf("%d",&w);
        cin>>w;
        W[i]=w;
    }
    
    init(huffmanTree,W,Z,n);
    setHuffmanTree(huffmanTree,n);
    huffmanTreeCode(huffmanTree,n);
    for(i=0;i<n;i++)
    {
        printf("%c:%s\n",huffmanTree[i].ch,huffmanTree[i].hCode);
    }
    return 0;
}

代码执行结果:

三、算法优缺点总结

优点:
   高效性:优秀的算法能够在较短的时间内解决问题,提高计算效率。
   可读性: 一些算法设计得清晰简洁,易于理解和阅读。
   稳定性:一些算法在不同数据情况下表现稳定,对输入变化不敏感。
   可靠性: 经过验证和测试的算法能够产生正确的结果。

缺点:
   资源占用:某些算法可能对计算资源(时间和空间)要求较高。
   问题依赖性:有些算法在处理特定问题时表现出色,但对其他问题可能不适用。

算法的应用方面:

1. 排序算法
 优点:高效地对数据进行排序,提高检索速度。
应用: 数据库检索、搜索引擎、数据分析。

 2.搜索算法
优点:快速定位目标数据。
应用:数据库查询、图像处理、人工智能搜索。

 3. 图算法:
   优点:解决图相关的问题,如路径查找、最短路径等。
   应用:网络路由、社交网络分析、城市规划。

4. 动态规划:
   优点: 解决最优化问题,避免重复计算。
   应用:背包问题、最短路径问题、游戏策略。

 5. 哈希算法
   优点:快速查找、插入和删除。
   应用:数据库索引、密码学、数据缓存。

6. 贪心算法:
   优点: 简单、高效,通常用于最优化问题。
   应用:调度问题、最小生成树、任务分配。

大家点赞、收藏、关注、评论啦 !

谢谢哦!如果不懂,欢迎大家下方讨论学习哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/343394.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开发实战角度:distinct实现原理及具体优化总结

1.背景 Distinct是一种常用的操作&#xff0c;在所有数据库的SQl语言中都是一个非常重要的操作&#xff0c;在Hive中&#xff0c;Distinct去重原理是通过MapReduce来实现的&#xff0c;Distinct操作可以应用于单个列&#xff0c;亦可以应用于多个列。基本原理是将输入的数据集…

基于SpringBoot的教务管理系统设计与实现(源码+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于SpringBoot的教务管…

StableDiffusion新版汉化

新旧版不同&#xff0c;这里以新版为例&#xff0c;用的是带链接&#xff0c;可以更新的方法。 步骤&#xff1a; 1.找到这个位置&#xff0c;依次点击&#xff0c;注意选项。 2.点击加载&#xff0c;等待刷新。 ctrlF搜索 zh_CN Localization 右边点击install&#xff0c…

[Linux 杂货铺] —— 权限(文件权限和目录配置)

目录 &#x1f308;前言 &#x1f4c1; 文件的属性 &#x1f4c1; 权限的概念 &#x1f4c2;拥有者和所属组&#xff08;角色&#xff09;&#xff1a; &#x1f4c2;用户&#xff08;具体的人&#xff09;&#xff1a; &#x1f4c1; 权限的管理 &#x1f4c2;1. chmod…

Object.defineProperty、Proxy、Reflect-个人总结

Object.defineProperty 前言 用于给一个对象添加或者修改一个属性&#xff0c;返回操作后的对象。 写法&#xff1a;Object.defineProperty(对象&#xff0c;属性&#xff0c;配置对象) 配置对象 通过对配置对象不同的配置&#xff0c;可以将属性分为数据属性和存取属性。 数据…

[Linux]HTTP状态响应码列举

1xx&#xff1a;信息响应类&#xff0c;表示接收到请求并且继续处理 2xx&#xff1a;处理成功响应类&#xff0c;表示动作被成功接收、理解和接受 3xx&#xff1a;重定向响应类&#xff0c;为了完成指定的动作&#xff0c;必须接受进一步处理 4xx&#xff1a;客户端错误&#x…

7.Feign远程调用

2.Feign远程调用 先来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; 存在下面的问题&#xff1a; •代码可读性差&#xff0c;编程体验不统一 •参数复杂URL难以维护 Feign是一个声明式的http客户端&#xff0c;官方地址&#xff1a;https://github.com/OpenF…

RabbitMQ消息应答与发布

消息应答 RabbitMQ一旦向消费者发送了一个消息,便立即将该消息,标记为删除. 消费者完成一个任务可能需要一段时间,如果其中一个消费者处理一个很长的任务并仅仅执行了一半就突然挂掉了,在这种情况下,我们将丢失正在处理的消息,后续给消费者发送的消息也就无法接收到了. 为了…

【BIAI】Lecture 6 - Somatosensory systems

Lecture 6- Somatosensory systems 专业术语 somatosensory system 体感系统 Thermoreceptors 温度感受器 Photoreceptors 光感受器 Chemoreceptoprs 化学感受器 hairy skin 毛发皮肤 glabrous skin 光滑皮肤 sensory receptors 感觉受体 dermal 真皮的 epidermal 表皮的 axon…

外包干了2个多月,技术退步明显。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

创建高打开率邮件标题的技巧:吸引潜在客户的秘诀

邮件打开率是指什么&#xff1f; 邮件打开率是指打开邮件的人数占发送的收件人总人数的比例。 邮件的打开率是衡量营销效果如何的一个非常重要的指标&#xff0c;而邮件标题又是影响邮件打开率非常重要的因素之一。所以&#xff0c;我们要要重视邮件标题。那我们应该如何编辑…

《移动通信原理与应用》——QPSK调制解调仿真

目录 一、QPSK调制与解调流程图&#xff1a; 二、仿真运行结果&#xff1a; 三、MATLAB仿真代码&#xff1a; 一、QPSK调制与解调流程图&#xff1a; QPSK调制流程图&#xff1a; QPSK解调流程图&#xff1a; 二、仿真运行结果&#xff1a; 1、Figure1:为发送端比特流情…

深入了解WPF控件:常用属性与用法(七)

掌握WPF控件&#xff1a;熟练常用属性&#xff08;七&#xff09; Menu 用于为应用程序指定命令或选项的项列表。它允许用户通过选择不同的菜单项来执行不同的命令或操作。 每个 Menu 可以包含多个 MenuItem 控件。 每个 MenuItem 都可以调用命令或调用 Click 事件处理程序。…

竞赛保研 电影评论情感分析 - python 深度学习 情感分类

1 前言 &#x1f525;学长分享优质竞赛项目&#xff0c;今天要分享的是 &#x1f6a9; GRU的 电影评论情感分析 - python 深度学习 情感分类 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 这…

vue3-组件基础

什么是组件 组件允许我们将 UI 划分为独立的、可重用的部分&#xff0c;并且可以对每个部分进行处理。在实际应用中&#xff0c;组件常常被组织成层层嵌套的树状结构。 定义一个组件 我们一般会将 Vue 组件定义在一个单独的 .vue 文件中&#xff0c;这被叫做单文件组件 (简称…

【加速】Ubuntu 22.04 LTS Steam++ Watt Toolkit 加速 github

项目地址 SteamTools: &#x1f6e0;「Watt Toolkit」是一个开源跨平台的多功能 Steam 工具箱。 下载linux版本 wget https://gitee.com/rmbgame/SteamTools/releases/download/3.0.0-rc.3/Steam%20%20_v3.0.0-rc.3_linux_x64.tgz 解压到/opt/steam sudo mkdir /opt/steam…

【C语言】扫雷游戏完整代码实现

目录 1.game.h 2.game.c 3.progress.c 4.运行结果 1.game.h #define _CRT_SECURE_NO_WARNINGS#include <string.h> #include <stdio.h> #include <time.h> #include<stdlib.h>#define ROW 9 #define COL 9 #define ROWS 11 #define COLS 11 #defin…

ctfshow-反序列化(web271-web276)

目录 web271 web272-273 web274 web275 web276 为什么不用分析具体为什么能成功 ,后面会有几个专题 会对php框架进行更深入的了解 这里面会专门的研究 为什么能够实现RCE 前面作为初步的熟悉 首先知道一下他的框架 知道框架的风格 知道啥版本可以用什么来打 首先先不用太研…

CopyOnWriteArrayList源码

CopyOnWriteArrayList源码 介绍 CopyOnWriteArrayList底层采用数组对元素进行存储&#xff0c;采用写时复制技术:写的时候加锁&#xff0c;将原数组拷贝一份&#xff0c;对新数组进行操作&#xff0c;新数组长度为原数组长度1,写入完成后替换原数组&#xff0c;原数组使用vol…

【Linux】Vagrant搭建Linux环境

1. Vagrant Vagrant是一个基于Ruby的工具&#xff0c;用于创建和部署虚拟化开发环境。它使用Oracle的开源VirtualBox虚拟化系统&#xff0c;使用 Chef创建自动化虚拟环境。 1.1 安装Vagrant 从Vagrant官网下载安装包&#xff0c;执行安装。 1.2 安装VirtualBox 从官网下载…