利用c语言详细介绍下哈夫曼树的实现

哈夫曼树(C语言实现) 文章目录哈夫曼树的基本概念哈夫曼树的构建构建思路代码实现哈夫曼编码的生成编码生成思路代码实现完整代码展示以及代码测试 哈夫曼树的基本概念 在认识哈夫曼树之前,你必须知道以下几个基本术语: 1、什么是路径?  给定N个权值作为N个结点,构造一棵二叉树,若该树的带权路径长度达到最小,则称该二叉树为哈夫曼树,也被称为最优二叉树。 哈夫曼树的构建 构建思路 代码实现 哈夫曼编码的生成 编码生成思路 代码实现 完整代码展示以及代码测试 ... 阅读详情

    哈夫曼树,二叉树的一种,称为最优二叉树。给定N个权值作为N个叶子节点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为哈夫曼树。

 一、图文介绍

    我们给定六个节点,每个节点的权重为{3, 2, 5, 1, 9, 7}。

1.1,选取第一步

    我们选取最小权重的两个节点1和2,组成一个二叉树。

1.2,选取第二步

    第二步,我们第一步生成了一个新的权重为3的节点,我们再去剩余节点中找取最小权重的节点和它组成新的二叉树:

1.3,选取第三步

1.4,选取第四步和第五步

二、算法实现

2.1,初始化

    我们叶子节点有6个,那么最终二叉树节点必然有2*6-1=11个节点(2*n-1),所以我们一开始申请11个节点的动态堆空间:

struct huffmanNode
{
    unsigned  int weight;
    unsigned  int parent;
    unsigned  int lchild;
    unsigned  int rchild;
};

typedef struct huffmanNode * huffmanTree;

typedef char * * huffmanCode;


char ** huffmanCoding(huffmanTree,int);

void huffmanSelect(huffmanTree,int,int *,int *);

void freeHuffman(huffmanTree,huffmanCode);

void testHuffman();

void printHuffman(huffmanTree,int);

huffmanTree initHuffman(huffmanTree, unsigned int *,int);
huffmanTree initHuffman(huffmanTree ht, unsigned int *w,int n)
{
    if(n<=1)
        return NULL;

    int node = 2 * n - 1; //定义节点总数
    int w1,w2;

    ht = (huffmanTree)malloc(node*sizeof(struct huffmanNode)); //动态申请空间

    huffmanTree hp;
    int i;
    for(hp = ht,i = 1;i<=n;++i,++hp,++w){   //叶子节点初始化
        hp->weight = *w;
        hp->parent = 0;
        hp->lchild = -1;
        hp->rchild = -1;
    }
    for(;i<=node;++i,++hp){  //父节点初始化
        hp->weight = 0;
        hp->parent = 0;
        hp->lchild = -1;
        hp->rchild = -1;
    }
    for(i=n;i<node;++i)
    {
        huffmanSelect(ht,i,&w1,&w2);
        printf("the left clild index is:%d,the right child is:%d\n",w1,w2);
        if(w1!=w2)
        {
            ht[w1].parent = i;
            ht[w2].parent = i;
            ht[i].lchild = w1;
            ht[i].rchild = w2;
            ht[i].weight = ht[w1].weight + ht[w2].weight;
        }

    }
    return ht;
}

2.2,节点选择:

void huffmanSelect(huffmanTree ht,int n,int *s1,int *s2)
{
    int min1=10000,min2=10000;
    int idx1=0,idx2=0;

    for(int i=0;i<n;i++)
    {
        if(!ht[i].parent&&ht[i].weight<min1)
        {
            min2=min1;
            idx2=idx1;
            min1 = ht[i].weight;
            idx1 = i;
        }else if(!ht[i].parent&&ht[i].weight<=min2)
        {
            min2=ht[i].weight;
            idx2 = i;
        }
    }
    *s1 = idx1;
    *s2 = idx2;

}

2.3,哈夫曼编码

char ** huffmanCoding(huffmanTree ht,int n)
{


    huffmanCode hc = (huffmanCode)malloc((n+1)*sizeof(char *)); //动态申请指针数组空间
    char *cd = (char *)malloc(n*sizeof(char));  //动态申请哈夫曼编码字符串空间
    int idx;
    int cur;
    cd[n-1] = '\0';
    for(int i=0;i<n;i++)
    {
        char *pc = cd;  
        idx = ht[i].parent;  //最找父亲节点
        cur = i;
        while(idx!=0)
        {
            if(ht[idx].lchild==cur)  //如果当前节点为左节点,则编码为1
            {
                *pc++ = '1';
            } else if(ht[idx].rchild==cur)  //如果当前节点为左节点,则编码为0
            {
                *pc++ = '0';
            }
            cur = idx;
            idx = ht[idx].parent;
        }
        *pc = '\0';
        hc[i] = (char *)malloc((pc-cd)); 
        strcpy(hc[i],cd); //我们只拷贝需要的长度字符

    }
    free(cd);
    return hc;
}

2.4,打印哈夫曼和测试哈夫曼编码

void printHuffman(huffmanTree ht,int len)
{
    for(int i=0;i<len;i++)
    {
        int left = ht[i].lchild == -1?0:ht[ht[i].lchild].weight;
        int rigth = ht[i].rchild == -1?0:ht[ht[i].rchild].weight;
        int parent = ht[i].parent == 0?0:ht[ht[i].parent].weight;
        printf("the %d element weight is %d; lchild index is %d, lchild weight is %d, rchild index is %d, rchild weight is %d; parent index is %d parent weight is %d\n",i,ht[i].weight,ht[i].lchild,left,ht[i].rchild,rigth,ht[i].parent,parent);
    }
}

void testHuffman()
{
    huffmanTree ht = NULL;
    unsigned  int w[] = {3,2,5,1,9,7};
    ht = initHuffman(ht,w,6);
    huffmanCode hc ;
    hc = huffmanCoding(ht,6);
    printHuffman(ht,2*6-1);
    for(int i=0;i<6;i++)
    {
        printf("the element %d huffmancode is:",ht[i].weight);
        char *p = hc[i];
        int idx = 0;
        while(*p++){
            idx++; //记录编码长度
        }
        p = hc[i];
        char *t;
        for(t=p+idx;t>=p;t--){ //倒序输出编码
            printf("%c",*t);
        }
        printf("\n");
        //printf("%s\n",hc[i]);

    }
    freeHuffman(ht,hc);
}

2.5,结果

哈夫曼树(C++实现) 哈夫曼树的概念:在含有 n 个带权叶节点的二叉树中,其中带权路径长度(WPL)最小的二叉树,也叫做最优二叉树。 阅读详情

相关推荐

哈夫曼编码原理及实现

构建编码树的方法是将频率最低的两个符号合并为一个新节点,该节点的频率为两个节点频率之和。哈夫曼编码(Huffman Coding)是一种用于数据压缩的编码方法,它通过给出不同的数据符号分配不同长度的编码,使得出现频率高的符号具有较短的编码,而出现频率低的符号具有较长的编码,从而达到压缩数据的目的。然而,对于哈夫曼编码的最佳性能,符号的频率应该是根据数据集的统计特征进行调整的。由于频率高的符号具有较短的编码,而频率低的符号具有较长的编码,所以整个编码后的数据长度会相对减小。

qq_35803412的博客 5015

【数据结构】树(七)—— 哈夫曼树(C语言版)

【数据结构】树(七)—— 哈夫曼树(C语言版)前言哈夫曼树的定义哈夫曼树的应用——哈夫曼编码 前言 哈夫曼树的定义 哈夫曼树的应用——哈夫曼编码

haoweixl的博客 1万+

C语言实现哈夫曼树的构建

主要为大家详细介绍了C语言实现哈夫曼树的构建,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

哈夫曼树的代码实现

注意结构体中的child,parent均为数组下标。左子树全为0,右子树全为1。

QoQ_____________的博客 635

从零到一:Ubuntu22.04下VSCode与中文输入法的深度整合指南

本文详细介绍了在Ubuntu22.04系统中如何深度整合VSCode与中文输入法,包括环境准备、安装方案对比、输入法配置及常见问题解决方案。通过fcitx框架优化中文输入体验,提供从基础设置到高级调试的全方位指南,帮助开发者提升在Linux环境下的开发效率。

weixin_29158047的博客 481

NVIDIA DGX Spark实战指南:从开箱到部署200B参数大模型

本文详细介绍了NVIDIA DGX Spark桌面AI超级计算机的开箱体验与实战部署指南。文章深入解析了其Grace Blackwell架构与128GB统一内存的核心优势,并逐步演示了从系统初始化、运行200B参数大模型到进行QLoRA微调的全过程。该设备将高达1 PetaFLOP的AI算力浓缩于桌面,为开发者和研究团队提供了本地化、高性能的AI开发与部署一体化解决方案。

weixin_29274969的博客 2230

哈夫曼树的建立、编码和译码

哈夫曼树的建立、编码和译码 一、需求分析 设计任务:设字符集为26个英文字母,其出现频度如下表所示。 编程实现 (1)先建哈夫曼树, (2)再利用此树对报文“this program is my favorite”进行编码和译码。 (3)输入输出形式:输入字符和权值,创建一个哈夫曼树,输出它字符对应的权值、weight、parent、lchild、rchild,再输入报文This program is my favorite,输出编码完成后的一串二进制数,将这一串二进制数再输入译码部分,译码完成得到Thi

weixin_46020391的博客 8505

深度学习12—VGG19实现

state_dict = load_state_dict_from_url(model_urls['vgg19'],model_dir='./model' ,progress=progress)#预训练模型地址。accuracy=((out.argmax(1)==label).sum()).clone().detach().cpu().numpy()#正确预测的总和比测试集的长度,即预测正确的精度。image=torch.reshape(image,(1,3,224,224))#四维图形,RGB三个通。

m0_55196097的博客 2444

输入字符串,统计使用频率,并根据频率创建哈夫曼树

void Select(HuffmanTree HT,int n,int &s1,int &s2) //s1,s2要取地址。//动态分配数组存储哈夫曼编码表。printf("字符%c出现%d次\n",(char)i,num[i]);//分配存储n个字符编码的编码表空间。++i) //逐个字符求哈夫曼编码。//根据哈夫曼树求哈夫曼编码,存储在编码表HC中。{ // (1)统计字符串各字符的频率。//(1)统计字符串各字符的频率。//哈夫曼编码表的存储表示。//哈夫曼树的存储表示。

m0_72398927的博客 4444

UDS诊断服务基础详解之七-31服务

本节内容主要是讲解诊断服务中的31服务,包含31服务的使用场景,请求报文格式,响应报文格式,以及举例对31服务进行相关的说明

车载网络小D的博客 5629

EndNote X9 快速上手教程(毕业论文参考文献管理器)

EndNote X9 快速上手教程一、EndNote X9安装1.安装2 安装之后重要步骤二、第一次打开 EndNote三、参考文献引用1. 导入知网文献2. 参考文献引用四、常见问题1. 引用文献中出现%J的问题2 参考文献中出现et.al1 在文章中引用的编号的地方出现2 在参看文献列表里出现 一、EndNote X9安装 1.安装 打开文件夹 安装前,一定要读 #Readme.txt 文件 一定要把License.dat和ENX9Inst.msi放在同一文件夹,安装的时候会自动激活。 我的安装路

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 2万+

哈夫曼树的编码译码(注释超详细)

​ #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; //malloc函数和free()函数用到 #include &lt;string.h&gt; //strcpy函数用到 #define N 30 //最大的叶子数目 #define M 2*N-1 // 最大的结点个数(N...

wwcxrnsy的博客 1万+

自定义模型训练——打造专属OpenClaw模型(2026AI版)

本文介绍了OpenClaw自定义模型训练的核心流程,包括框架选择(PyTorch、TensorFlow、HuggingFace和原生OpenClaw框架)、训练环境搭建脚本、以及数据收集系统的设计。数据收集器支持从数据库、API、文件和网络等多种来源获取训练数据,并提供灵活的过滤机制确保数据质量。通过这套系统,开发者可以高效准备训练数据,为后续模型训练打下坚实基础。

博客 877

哈夫曼树的初始化,编码,译码及横向打印

哈夫曼树介绍:(好吧,部分copy自百度知道^_^)    哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+...+ Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。    利用哈夫曼编

the Pensieve 2万+

传导案例:某医疗仪器传导骚扰整改案例

紫外线光疗仪是一种专业的医疗设备,主要用于治疗银屑病、白癜风等皮肤疾病。该设备采用物理治疗技术,通过特定波长的紫外线照射人体来达到治疗效果。自1984年窄谱中波紫外线(NB-UVB)应用于临床以来,该技术已成为治疗早期蕈样肉芽肿(MF)的有效方法之一。作为二类医疗器械,紫外线光疗仪必须符合严格的电磁兼容性(EMC)标准,这不仅关系到设备自身的稳定运行,更关乎患者的使用安全和治疗效果。紫外线光疗仪传导骚扰整改案例充分展示了系统性EMC设计的重要性。

m0_56451176的博客 340

【异常】出现“‘git‘ 不是内部或外部命令,也不是可运行的程序”的错误

出现“‘git’ 不是内部或外部命令,也不是可运行的程序”的错误通常意味着 Git 没有被正确安装在你的系统上,或者其可执行文件的路径没有被添加到系统的环境变量中。

奶爸的编程之路,也就一周冷个三天 1391

数据结构之哈夫曼树

数据结构之哈夫曼树 先给出相关基本概念: 路径:从树中一个结点到另一个结点之间的路径。 路径长度:路径上分支的条数成为路径长度。 树的路径长度:从树根到每个结点的路径长度之和称为树的路径长度。 结点的权:给树中结点赋予一个数值,该数值称为结点的权。 带权路径长度:结点到树根间的路径长度与结点权的乘积,称为该结点的带权路径长度。 树的带权路径长度:树中所有叶子结点的带权路径长度之和,记为WPL。 最...

weixin_44517656的博客 2512

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C Language 树和二叉树 - 哈夫曼树(十六)

话不多说,直接上车~ 1.初识哈夫曼树 路径:从结点A到E之间路径为:A-C-D-E , 路径长度为3 结点带权路径长度:例如A-E之间的路径长度为3,带权路径为WPL(权重*路径长度)=3 * 8 = 24 哈夫曼树的研究是什么? 在n0个带权叶子结点构成的二叉树中,带权路径长度WPL最小的二叉树成为哈夫曼树(Huffman tree)或最优二叉树。 2.创建哈夫曼树(最优二叉树构造法) 带权叶子结点如下: 构造方法口诀: 构造森林全是根 在6个根之中,1、5权重是最小的,

FATCATS博客 1373

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

c语言递归计算哈夫曼编码,哈夫曼树遍历求WPL和哈夫曼编码C语言--For初学者

这篇文章使用纯c来写的,实现了生成哈夫曼树、求WPL和生成哈夫曼编码的应用,思路是,先定义一个结构体如下typedef struct node{int weight;struct node *lchild,*rchild;struct node *next;}HuffNode;先生成单链表(用next链接),还存储输入的权值(weight),单链表无头结点(因为最后要转化成二叉树,所以不用头结点)...

weixin_39664696的博客 1206

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C语言 数据结构 哈夫曼树的创建与哈夫曼编码

1、掌握哈夫曼树的三叉链表存储结构。2、掌握利用构造哈夫曼树的算法。3、掌握利用哈夫曼树进行哈夫曼编码及译码。

i13145821的博客 726

哈夫曼编/译码器

哈夫曼编/译码器 一、需求分析 1. 问题阐述 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编/译码系统。 2. 基本要求 一个完整的系统应具有以下功能: (1)I:初始化(initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树

clementchueng的博客 2862

哈夫曼树与哈夫曼编码

哈夫曼树 1. 定义 节点的路径长度:从根节点到该节点的路径上的连接数。 树的路径长度:树的叶子节点的路径长度之和。 节点带权路径长度:节点的路径长度与节点的权值的乘积。 树的带权路径长度:WPL(Weighted Path Length)是树中所有叶子节点的带权路径长度之和。 定义:给定n个权值作为n个叶子节点,构造一棵二叉树,若这棵二叉树的带权路径长度达到最小,则称这样的二叉树为最优二叉树,也称为Huffman树。 2. 构建哈夫曼树 **WPL的值越小,构造出来的二叉树的性能越优。**如何构造最优二

Junhao_Lu的博客 537

【数据结构】BOJ-3.2哈夫曼树的编码与译码(C语言)

【数据结构】哈夫曼树的编码与译码(C语言) 哈夫曼 #include <stdio.h> #include <stdlib.h> #include <string.h> #define LEN 8 typedef struct HaffTNode { int weight; struct HaffTNode *parent,*right,*left; }HaffTNode,*HaffTree; HaffTree CreatHaffTNode(int

weixin_46101687的博客 1332

哈夫曼树的实现与编码解码

哈夫曼树是一种带权路径长度最短的二叉树,通过合并权值最小的结点逐步构建而成。它具有无度为1结点、总结点数2n-1(n为叶子结点数)等特性。哈夫曼编码基于该树结构,利用不等长前缀编码实现数据压缩,高频字符对应短编码。C语言实现采用顺序存储结构,包含构建树、编码和解码三个核心函数。应用时需确保编解码使用相同的哈夫曼树结构,典型应用于ZIP、JPEG等压缩场景。该技术既解决了数据压缩问题,又体现了最优算法设计思想。

TH2983443454的博客 1038

哈夫曼树的构造与哈夫曼编码

#include<stdio.h> #include<string.h> #include<stdlib.h> #define N 20//叶子结点最大值 #define M 2*N-1//所有结点最大值 //静态三叉链表实现哈夫曼树 typedef struct Huffman{ int weight; int parent; int lchild; int r

我们的时光 2611

哈夫曼编码(C实现)

/*------------------------------------------------------------------------- * 实现过程:着先通过 HuffmanTree() 函数构造哈夫曼树,然后在主函数 main()中 * 自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在 * 父结点左侧,则置码为 0,若

zenglinshan的博客 1390
上一篇: 深入解析下oracle date底层存储方式
下一篇: 利用c语言详细介绍下串(String)的实现
TPCloud
博客等级 码龄16年 509粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TPCloud

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值