哈夫曼树与哈夫曼编码详解及C++模板实现

C++ 哈夫曼编码 1.哈夫曼编码的结点类: struct HuffmanNode { int weight; // 权重,出现的次数或者频率 char ch; // 存储符号 string code; // 存储该符号对应的编码 int leftChild, rightChild, parent; // 左、右孩子,父结点 }; 2.思路: (1)统计输入的字符串中不同字... 阅读详情

  哈夫曼树又称最优二叉树,是带权路径长度最短的树,可用来构造最优编码,用于信息传输、数据压缩等方面,是一种应用广泛的二叉树。
这里写图片描述

几个相关的基本概念:

1.路径:从树中一个结点到另一个结点之间的分支序列构成两个节点间的路径
2.路径长度:路径上的分支的条数称为路径长度
3.树的路径长度:从树根到每个结点的路径长度之和称为树的路径长度
4.结点的权:给树中结点赋予一个数值,该数值称为结点的权
5.带权路径长度:结点到树根间的路径长度与结点的权的乘积,称为该结点的带权路径长度
6.树的带权路径长度:树中所有叶子结点的带权路径长度之和,通常记为WPL
7.最优二叉树:在叶子个数n以及各叶子的权值确定的条件下,树的带权路径长度WPL值最下的二叉树称为最优二叉树。

哈夫曼树的建立

由哈夫曼最早给出的建立最优二叉树的带有一般规律的算法,俗称哈夫曼算法。描述如下:
1):初始化:根据给定的n个权值(W1,W2,…,Wn),构造n棵二叉树的森林集合F={T1,T2,…,Tn},其中每棵二叉树Ti只有一个权值为Wi的根节点,左右子树均为空。

2):找最小树并构造新树:在森林集合F中选取两棵根的权值最小的树做为左右子树构造一棵新的二叉树,新的二叉树的根结点为新增加的结点,其权值为左右子树的权值之和。

3):删除与插入:在森林集合F中删除已选取的两棵根的权值最小的树,同时将新构造的二叉树加入到森林集合F中。

4):重复2)和3)步骤,直至森林集合F中只含一棵树为止,这颗树便是哈夫曼树,即最优二叉树。由于2)和3)步骤每重复一次,删除掉两棵树,增加一棵树,所以2)和3)步骤重复n-1次即可获得哈夫曼树。

下图展示了有4个叶子且权值分别为{9,6,3,1}的一棵最优二叉树的建立过程。


这里写图片描述

这里写图片描述

这里写图片描述

C++类模板构造哈夫曼树

哈夫曼树的节点结构
/*哈夫曼树的节点定义*/
template <typename T>
struct HuffmanNode
{
    //初始化
    HuffmanNode(T k,HuffmanNode<T>* l,HuffmanNode<T>* r):key(k),lchild(l),rchild(r),flag(0) {}

    T key;                  //节点权值
    HuffmanNode<T>* lchild; //节点左孩
    HuffmanNode<T>* rchild; //节点右孩
    int flag;               //标志 判断是否从森林中删除
};
哈夫曼树的抽象数据类型
template <typename T>
class Huffman
{
public:
    void preOrder();        //前序遍历哈夫曼树
    void inOrder();         //中序遍历哈夫曼树
    void postOrder();       //后序遍历哈夫曼树

    void creat(T a[],int size); //创建哈夫曼树
    void destory();             //销毁哈夫曼树
    void print();               //打印哈夫曼树

    void my_sort(int size);
    Huffman():root(NULL) {}
    ~Huffman(){
        destory(root);
    }
private:
    void preOrder(HuffmanNode<T>* pnode);   //前序遍历二叉树
    void inOrder(HuffmanNode<T>* pnode);    //中序遍历二叉树
    void postOrder(HuffmanNode<T>* pnode);  //后序遍历二叉树
    void print(HuffmanNode<T>* pnode);      //打印二叉树
    void destory(HuffmanNode<T>* pnode);    //销毁二叉树

    HuffmanNode<T>* root;            //哈夫曼树根节点
    HuffmanNode<T>* forest[MAXSIZE]; //用数组来存储森林中树的根节点
};
具体实现
/*自写排序*/
template <typename T>
void Huffman<T>::my_sort(int size)
{
    for(int i=0;i<size-1;i++)
    {
        for(int j=i+1;j<size;j++)
        {
            if(forest[i]->key > forest[j]->key)
            {
                swap(forest[i],forest[j]);
            }
            else
                continue;
        }
    }
};

/*创建哈夫曼树*/
template <typename T>
void Huffman<T>::creat(T a[],int size)
{
    int j,k=0;
    /*每个节点都作为一个森林*/
    for(int i=0; i<size; i++)  
    {
        HuffmanNode<T>* ptr = new HuffmanNode<T>(a[i],NULL,NULL);
        forest[i] = ptr; //双向队列尾部加入一个元素
    }
    for(int i=0; i<size-1; i++)
    {
        /*排序 选出根节点权值最小的两棵树*/
        my_sort(size+k);
        for(j=0; ; j++)
        {
            if(forest[j]->flag!=1 && forest[j+1]->flag != 1)
            {
                /*构建新节点*/
                HuffmanNode<T>* node = new HuffmanNode<T>(forest[j]->key + forest[j+1]->key,forest[j],forest[j+1]);  
                /*新节点加入森林中*/
                forest[size+k] = node;
                k++;
                /*删除两棵权值最小的树*/
                forest[j]->flag = 1;
                forest[j+1]->flag = 1;
                break;
            }
            else
                continue;
        }
    }
    root  = forest[size+k-1];
};

/*前序遍历哈夫曼树*/
template <typename T>
void Huffman<T>::preOrder(HuffmanNode<T>* pnode)
{
    if(pnode != NULL)
    {
        cout << pnode -> key;
        preOrder(pnode->lchild);
        preOrder(pnode->rchild);
    }
};
template <typename T>
void Huffman<T>::preOrder()
{
    preOrder(root);
};

/*中序遍历哈夫曼树*/
template <typename T>
void Huffman<T>::inOrder(HuffmanNode<T>* pnode)
{
    if(pnode != NULL)
    {
        inOrder(pnode->lchild);
        cout << pnode -> key;
        inOrder(pnode->rchild);
    }
};
template <typename T>
void Huffman<T>::inOrder()
{
    inOrder(root);
};

/*后序遍历哈夫曼树*/
template <typename T>
void Huffman<T>::postOrder(HuffmanNode<T>* pnode)
{
    if(pnode != NULL)
    {
        postOrder(pnode->lchild);
        postOrder(pnode->rchild);
        cout << pnode -> key;
    }
};
template <typename T>
void Huffman<T>::postOrder()
{
    postOrder(root);
};

/*打印哈夫曼树*/
template <typename T>
void Huffman<T>::print(HuffmanNode<T>* pnode)
{
    if(pnode != NULL)
    {
        cout << "当前结点:" << pnode -> key << ".";
        if(pnode -> lchild != NULL)
            cout << "它的左孩子结点为:" << pnode->lchild->key << ".";
        else
            cout << "它没有左孩子.";
        if(pnode -> rchild != NULL)
            cout << "它的右孩子结点为:" << pnode->rchild->key << ".";
        else
            cout << "它没有右孩子.";
        cout << endl;
        print(pnode->lchild);
        print(pnode->rchild);
    }
};
template <typename T>
void Huffman<T>::print()
{
    print(root);  
};

/*销毁哈夫曼树*/
template <typename T>
void Huffman<T>::destory(HuffmanNode<T>* pnode)
{
    if( pnode!= NULL)    
    {
        destory(pnode->lchild);
        destory(pnode->rchild);
        delete pnode;
        pnode = NULL;
    }
};
template <typename T>
void Huffman<T>::destory()
{
    destory(root);
};

哈夫曼树代码测试

int main()
{
    Huffman<int> huff;
    int a[] = {10,20,30,40};
    huff.creat(a,4);
    huff.print();
    return 0;
}

输出结果:

当前结点:100.它的左孩子结点为:40.它的右孩子结点为:60.
当前结点:40.它没有左孩子.它没有右孩子.
当前结点:60.它的左孩子结点为:30.它的右孩子结点为:30.
当前结点:30.它没有左孩子.它没有右孩子.
当前结点:30.它的左孩子结点为:10.它的右孩子结点为:20.
当前结点:10.它没有左孩子.它没有右孩子.
当前结点:20.它没有左孩子.它没有右孩子.

  昨天下午就开始写了,本来使用deque双向队列来存储森林中树的根节点,结果在排序找出权值最小的两棵树的时候遇到了麻烦,换了几种方式都是编译错误,折磨了几个小时。后来选择用数组来存储,今天下午试着写了一下,总算整出来了,还有待优化,分享一下吧,整个思路过程都有注释,下来在慢慢改。下面看哈夫曼编码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
   unsigned int weight;
   unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; 

typedef char **HuffmanCode;

int Select(HuffmanTree HT, int n, int *s1, int *s2)
{  
//在HT[1..n]中选择parent为0且weight最小的两个结点,
// 其序号分别为s1和s2。
    int i,j,k,flag;
    int count = 0;

    for(i=1; i<=n; i++)
    {
        if(HT[i].parent == 0)
            count++;
    }
    if(count == 0)
        return 1;
    *s1 = 0;
    *s2 = 0;
    for(i=1; i<=n; i++)
    {
        if(HT[i].parent != 0)
            continue;
        if(HT[i].weight < HT[*s1].weight)
            *s1 = i;
    }
    for(int j=1; j<=n; j++)
    {
        if(HT[j].parent != 0)
            continue;
        if(HT[j].weight < HT[*s2].weight && j != *s1)
            *s2 = j;
    }
}


void create_HuffmanTree(HuffmanTree HT,HuffmanCode HC,int *w,int n)
{
    int start;
    char *cd;
    // 并求出n个字符的哈夫曼编码HC
    int i, m, s1=0, s2=0;
    unsigned int c, f;
    if (n<=1) return;
    m = 2 * n - 1;
    HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));  // 0号单元未用
    HT[0].weight = 99999;
    for(i=1; i<=n; i++) { //初始化
        HT[i].weight=w[i-1];
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
    }
    for (i=n+1; i<=m; i++) { //初始化
        HT[i].weight=0;
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
    }
    for (i=n+1; i<=m; i++) {  // 建哈夫曼树
        // 在HT[1..i-1]中选择parent为0且weight最小的两个结点,
        // 其序号分别为s1和s2。
        Select(HT, i-1, &s1, &s2);
        printf("%d  %d\n",s1,s2);
        HT[s1].parent = i;  HT[s2].parent = i;
        HT[i].lchild = s1;  HT[i].rchild = s2;
        HT[i].weight = HT[s1].weight + HT[s2].weight;
    }

   //--- 从叶子到根逆向求每个字符的哈夫曼编码 ---
    cd = (char *)malloc(n*sizeof(char));    // 分配求编码的工作空间
    cd[n-1] = '\0';                         // 编码结束符。
    for (i=1; i<=n; ++i) {                  // 逐个字符求哈夫曼编码
        start = n-1;                          // 编码结束符位置
        for (c=i, f=HT[i].parent; f!=0; c=f, f=HT[f].parent) 
        // 从叶子到根逆向求编码
        if (HT[f].lchild==c) cd[--start] = '0';
        else cd[--start] = '1';
        HC[i] = (char *)malloc((n-start)*sizeof(char)); 
        // 为第i个字符编码分配空间
        strcpy(HC[i], &cd[start]);    // 从cd复制编码(串)到HC   
    }
    free(cd);   //释放工作空间
} //HuffmanCoding

void HuffmanCoding(HuffmanTree HT,HuffmanCode HC,int *w,int n)
{
    int start;
    char *cd;
    // 并求出n个字符的哈夫曼编码HC
    int i, m, s1=0, s2=0;
    unsigned int c, f;
    if (n<=1) return;
    m = 2 * n - 1;
    HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));  // 0号单元未用
    HT[0].weight = 99999;
    for(i=1; i<=n; i++) { //初始化
        HT[i].weight=w[i-1];
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
    }
    for (i=n+1; i<=m; i++) { //初始化
        HT[i].weight=0;
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
    }
    for (i=n+1; i<=m; i++) {  // 建哈夫曼树
        // 在HT[1..i-1]中选择parent为0且weight最小的两个结点,
        // 其序号分别为s1和s2。
        Select(HT, i-1, &s1, &s2);
        HT[s1].parent = i;  HT[s2].parent = i;
        HT[i].lchild = s1;  HT[i].rchild = s2;
        HT[i].weight = HT[s1].weight + HT[s2].weight;
    }

   //--- 从叶子到根逆向求每个字符的哈夫曼编码 ---
    cd = (char *)malloc(n*sizeof(char));    // 分配求编码的工作空间
    cd[n-1] = '\0';                         // 编码结束符。
    for (i=1; i<=n; ++i) {                  // 逐个字符求哈夫曼编码
        start = n-1;                          // 编码结束符位置
        for (c=i, f=HT[i].parent; f!=0; c=f, f=HT[f].parent) 
        // 从叶子到根逆向求编码
        if (HT[f].lchild==c) cd[--start] = '0';
        else cd[--start] = '1';
        HC[i] = (char *)malloc((n-start)*sizeof(char)); 
        // 为第i个字符编码分配空间
        strcpy(HC[i], &cd[start]);    // 从cd复制编码(串)到HC   
    }
    free(cd);   //释放工作空间

    char *code;
    //译码
    code = (char *)malloc(50*sizeof(char));
    printf("请输入编码: ");
    scanf("%s",code);
    HTNode pnode = HT[m];
    for(int q=0; code[q]!='\0'; q++)
    {
        if(code[q] == '0')
        {
            pnode = HT[pnode.lchild];
            if(pnode.rchild == 0 && pnode.lchild == 0)
            {
                printf("%d ",pnode.weight);
                pnode = HT[m];
            }
        }

        if(code[q] == '1')
        {
            pnode = HT[pnode.rchild];
            if(pnode.rchild == 0 && pnode.lchild == 0)
            {
                printf("%d ",pnode.weight);
                pnode = HT[m];
            }
        }
    }
} //HuffmanCode

int main()
{
    int i,n,choice;
    int *w;
    HuffmanTree HT;
    HuffmanCode HC;
    printf("Node Number: ");
    scanf("%d",&n);  //权值个数
    w=(int *)malloc(n*sizeof(int));  
    printf("Input weights:");
    for ( i=0;i<n;i++)  //录入权值
        scanf("%d",&w[i]);

    HC=(char **)malloc((n+1)*sizeof(char*)); //0空间未用
    HT=(HuffmanTree)malloc((2*n+1+1)*sizeof(HTNode));//0空间未用
    printf("仅编码选择1,译码请选择2: ");
    scanf("%d",&choice);
    if(choice == 1)
    {
        create_HuffmanTree(HT,HC,w,n);
        for (i = 1; i<n+1; i++)
        {
            printf("%s\n", HC[i]);  //输出哈夫曼编码
            free(HC[i]);  //释放空间
        }
    }
    if(choice == 2)
        HuffmanCoding(HT,HC,w,n);   
   free(HC);
   free(HT);
   return 0;
}
哈夫曼编码(C++实现) 哈夫曼树是用来创建哈夫曼编码的。哈夫曼编码是一种可以用于数据压缩的编码方式,哈夫曼编码的构造过程需要用到哈夫曼树。 阅读详情

相关推荐

哈夫曼编码及文本文件的压缩解压(c++SourceCode)

哈夫曼编码是一种编码方式,是可变字长编码(VLC)的一种。以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据 压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。这一术语是指使用一张特殊的 编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出 现概率高

dooder_daodao的专栏 1万+

数据结构之二叉树应用(哈夫曼树及哈夫曼编码实现)(C++)

1.书上用的是静态链表实现,本文中的哈夫曼树用 排序链表 实现;2.实现了从 字符频率统计、构建权值集合、创建哈夫曼树、生成哈夫曼编码,最后对 给定字符串的编码、解码功能。//文件名:"HfmTree.h" #pragma once #include "SortedList.h" //"C1_Test.h" 排序列表 #include &lt;string&gt; using namespace...

碣石观海的博客 1万+

哈夫曼树与编码的深度解析与C++模板实践

在信息技术领域中,数据压缩是一个核心议题。哈夫曼编码作为广泛使用的无损压缩技术之一,其背后的数据结构——哈夫曼树,起着至关重要的作用。本章旨在介绍哈夫曼树的基本概念,并分析其在数据处理领域中的应用价值。

weixin_29607511的博客 631

哈夫曼树与哈夫曼编码(c++实现)

哈夫曼树与哈夫曼编码一、字符的机内表示二、 哈夫曼树的概念三、 哈夫曼树的理论实现四、 哈夫曼树的代码实现理论设计代码实现代码总结和测试 一、字符的机内表示 在计算机中每个西文字符是用一个编码表示,大多数编码系统都采用等长编码,如ASCII编码 例如在某段文本中用到了下列字符,括号中是它们出现的频率:a(10), e(15), i(12), s(3), t(4), 空格(13), 换行(1)。如采用定长编码,7个不同的字符至少要用3位编码。 下图给出了一种编码对应方法: 上述编码形式可以对应下面的二叉树,

H.A.N.的博客 7538

C#开发医学影像胶片打印系统(一):万能花式布局的实现思路

本篇文章将介绍开发医学影像胶片打印系统(printscu模式)遇到不规则排版时的一种思路,一般来讲,医院打印胶片时都是整张胶片打印,但有时需要将多个病人或一个病人的多个检查打印在同一张胶片上,这时候就需要不规则排版来满足打印需求,使胶片利用率最大化。

罗万科技的博客 1325

四足机器人如何用对抗运动先验(AMP)实现复杂地形行走?Unitree Go1实战解析

本文深入解析了四足机器人Unitree Go1如何通过对抗运动先验(AMP)算法实现复杂地形行走。AMP结合模仿学习与对抗训练,使机器人仅凭本体感知就能适应未知地形。文章详细介绍了AMP的核心架构、仿真训练工程实践以及在Unitree Go1上的部署优化方案,展示了其在极端地形下的卓越性能表现。

weixin_29050513的博客 327

c++哈夫曼编码与哈夫曼树

给定 N 个权值作为 N 个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树 (Huffman Tree)。相关概念:1、路径和路径长度在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为 1 ,则从根结点到第 L 层结点的路径长度为 L−1。2、结点的权及带权路径长度若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。

yzc_qiuse的博客 185

蓝牙 - 如何在Windows下抓取蓝牙数据

选择Windows Instarller(64-bit),最好不要选择PortableApps版,因为后面需要通过btvs.exe来启动Wireshark,如果是绿色可移植版,会启动失败。在安装完以后,找到btvs.exe文件,位于路径:C:\BTP\v1.14.0\x86下,这个视安装版本不同路径名不同。在第一台机器上启动btvs.exe,第二台机器上手动启动wireshark,并将第一台机器的IP地址作为参数。1,同一机器上,Wireshark安装后,会自动直接启动,如上面使用方式一样。

guoqx的专栏 2万+

huffman树_数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

作者:melonstreet链接:https://www.cnblogs.com/QG-whz/p/5175485.html1、哈夫曼编码简介哈夫曼编码(Huffman Coding)是一种编码方式,也称为“赫夫曼编码”,是David A. Huffman1952年发明的一种构建极小多余编码的方法。在计算机数据处理中,霍夫曼编码使用变长编码表对源符号进行编码,出现频率较高的源符号采用较...

weixin_39950083的博客 796

西门子PLC1200 1214C DC/DC/DC 驱动步进电机

控制电机旋转的指令在“指令”中的“工艺”下的“Motion Control”(若出现程序块无法调用情况,则看备注3的第4条),本篇只介绍常用指令(若想学习详细与更多指令,请参考指令手册)。

2301_79553921的博客 1万+

Python 爬虫实战:破解网页 JS 混淆加密参数

摘要:本文针对Python爬虫破解JS混淆加密参数的技术难题,系统解析了变量混淆、控制流混淆、AES/MD5加密混淆等常见类型及其检测方法,提出"定位-还原-复现"的三步破解策略。通过实战案例详细演示了从JS逆向分析到Python代码实现的完整流程,包括MD5签名生成、AES加密复现等核心代码实现,并对不同混淆场景的破解方法进行了对比分析。文中特别强调技术应用的合规性边界,指出开发者应遵守相关法律法规,在合理范围内使用逆向技术。随着反爬技术升级,建议开发者持续学习动态调试等进阶技能,同时

2503_91057718的博客 2067

C#量化交易的市场数据采集与分析:从0到1构建你的‘数据雷达’——对比5大神器,代码实战全解析!

数据是量化交易的‘氧气’,而好的数据采集与分析是你的‘呼吸机’!本文5大神器+代码实战,总有一款适合你!(本文代码均经过测试,但请根据实际需求调整!

java专栏 730

数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 数据结构图文解析之:树的简介及二叉排序树C++模板实现. 数据结构图文解析之:AVL树详解及C++模板实现 数据结构图文解析之:二叉堆详解及C++模板实现 数据结...

weixin_33670713的博客 527

Claude Code、Codex、Gemini CLI、OpenCode 和 OpenClaw 配置管理太麻烦?试试这个统一管理工具

还在为 Claude Code、Codex、Gemini CLI 等 AI CLI 配置烦恼?🤯 这款桌面工具支持五大助手统一管理,一键切换 50+ 服务商,MCP 和 Skills 集中管理 🛠️,跨平台支持,让你的 AI 编程更高效 ⚡

XiaoqiangClub的博客 913

链接文件及功能安全:Hightec如何将Flash驱动放进RAM

Fls本身是无法操作自身的,犯冲突。Fls_WriteCmdCycles (预留300字节)与 Fls_EraseCmdCycles(预留200字节) 函数在执行之前将会Copy进RAM,Fls本身是不能操作Fls本身的,除非把最底层的驱动函数防止在RAM或者其他的Flash里面,假设Flash放置在PF0可以操作PF1。英飞凌的驱动有个规定写指令预留300字节,擦除指令预留200字节。

梦想技术家 2141

C++哈夫曼树+哈夫曼编码的实现(双完整版)

C++版全网最全、详解、引导思考的哈夫曼树和哈夫曼编码讲解,剖析了关键代码,适合收藏~

不负AC不负卿的博客 2万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

哈夫曼树C++实现

哈夫曼树 给定一组具有确定权值的叶子结点,可以造出不同的二叉树,将其中带权路径长度最小的二叉树称为哈夫曼树(Huffman tree)。 哈夫曼节点类 哈夫曼节点会存储节点的权重以及,ch是节点对应的编码字符的下标,这里需要重载“<”,因为我们要使用最小优先级队列。 //哈夫曼树节点类 class hfTNode { public: int weight;//节点的权重 int ch;//存储节点的下标 hfTNode* leftchild, * rightchild;//创建该结点的

My_Algorithm的博客 6754

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【洛谷】贪心专题之哈夫曼编码 从原理到模板题解析

本文梳理哈夫曼编码的前置知识(哈夫曼树构造、带权路径长度计算),讲解哈夫曼编码的核心逻辑,结合 “哈夫曼编码模板题” 与 “合并果子” 经典问题,分析解题思路并给出代码实现,帮助读者掌握哈夫曼算法的原理与工程应用。

2501_90265152的博客 1202

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

哈夫曼树与哈夫曼算法

本文介绍了哈夫曼编码这一经典无损数据压缩算法。哈夫曼树作为带权路径长度最小的最优二叉树,通过贪心策略构建:将权值最小的两棵树合并,直到所有节点合为一树。在编码应用中,字符出现次数作为权值构建哈夫曼树,左分支为0、右为1,形成最短前缀编码。文章通过例题展示了如何计算编码后的最短字符串长度,并提供了优先队列实现的C++代码。哈夫曼编码以其高效性广泛应用于文件压缩、通信传输等领域,是理解数据压缩原理的重要算法。

2502_90265864的博客 826

c++实验8 哈夫曼编码-译码器

哈夫曼编码-译码器 此次实验的注释解析多加不少---若对小伙伴们有帮助 希望各位麻烦点个关注 多谢 1.哈夫曼树构造算法为:   (1)由给定的n个权值{w1,w2,…,wn}构造n棵只有根结点的二叉树,从而得到一个二叉树森林F={T1,T2,…,Tn}。  (2)在二叉树森林F中选取根结点的权值最小和次小的两棵二叉树作为新的二叉树的左右子树构造新的二叉树,新的二叉树的根结点权值为左右子树根...

weixin_30344795的博客 1184

哈夫曼编码(C++优先队列实现)

哈夫曼编码(C++优先队列实现) 使用变长编码表对字符进行编码,出现频率高的字符采用较短的编码,出现频率低的采用较长的编码。以达到编码后的字符串的平均长度尽可能短,以达到无损压缩数据的目的。 图解 有一字符串string word = "abbbcccccdddddddd",字符a,b,c,d权重分别为1,3,5,8。 初始 #mermaid-svg-mjsZwwZkUyfMBRSe .label{font-family:'trebuchet ms', verdana, arial;font-family:

leoabcd12的博客 1678

哈夫曼编码+哈夫曼树

百度百科简介: 1.哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。 2.哈夫曼树给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权

yhhy666的博客 314
上一篇: 队列的简介与C++模板实现
下一篇: 二叉查找树及C++模板实现
Tanswer_
博客等级 码龄11年 231粉丝 91原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值