哈夫曼算法构造代码

 更新时间:2013年12月23日 16:12:18   作者:  
这篇文章主要介绍了哈夫曼算法构造代码,有需要的朋友可以参考一下

1.定义

  哈夫曼编码主要用于数据压缩。

  哈夫曼编码是一种可变长编码。该编码将出现频率高的字符,使用短编码;将出现频率低的字符,使用长编码。

  变长编码的主要问题是,必须实现非前缀编码,即在一个字符集中,任何一个字符的编码都不是另一个字符编码的前缀。如:0、10就是非前缀编码,而0、01不是非前缀编码。

2.哈夫曼树的构造

  按照字符出现的频率,总是选择当前具有较小频率的两个节点,组合为一个新的节点,循环此过程知道只剩下一个节点为止。

  对于5个字符A、B、C、D、E,频率分别用1、5、7、9、6表示,则构造树的过程如下:

上面过程对应的哈夫曼树为:

假设规定左边为0,右边为1,则变长编码为:

  A 1:010

  B 5:011

  C 7:10

  D 9:11

  E 6: 00

3.哈夫曼构造代码

复制代码 代码如下:

#include <iostream>
#include <string.h>
using namespace std;
struct Node{
    char c;
    int value;
    int par;
    char tag;    //tag='0',表示左边;tag='1',表示右边
    bool isUsed;    //判断这个点是否已经用过
    Node(){
        par=-1;
        isUsed=false;
    }
};

int input(Node*,int);   //输入节点信息
int buildedTree(Node*,int); //建哈夫曼树
int getMin(Node*,int);  //寻找未使用的,具有最小频率值的节点
int outCoding(Node*,int);   //输出哈夫曼编码

int main ()
{
    int n;
    cin>>n;
    Node *nodes=new Node[2*n-1];
    input(nodes,n);
    buildedTree(nodes,n);
    outCoding(nodes,n);
    delete(nodes);
    return 0;
}

int input(Node* nodes,int n){
    for(int i=0;i<n;i++){
        cin>>(nodes+i)->c;
        cin>>(nodes+i)->value;
    }
    return 0;
}

int buildedTree(Node* nodes,int n){
    int last=2*n-1;
    int t1,t2;
    for(int i=n;i<last;i++){
        t1=getMin(nodes,i);
        t2=getMin(nodes,i);
        (nodes+t1)->par=i; (nodes+t1)->tag='0';
        (nodes+t2)->par=i; (nodes+t2)->tag='1';
        (nodes+i)->value=(nodes+t1)->value+(nodes+t2)->value;
    }
    return 0;
}

int getMin(Node* nodes,int n){
    int minValue=10000000;
    int pos=0;
    for(int i=0;i<n;i++)
    {
        if((nodes+i)->isUsed == false && (nodes+i)->value<minValue){
            minValue=(nodes+i)->value;
            pos=i;
        }
    }
    (nodes+pos)->isUsed=true;
    return pos;
}

int outCoding(Node* nodes,int n){
    char a[100];
    int pos,k,j;
    char tmp;
    for(int i=0;i<n;i++){
        k=0;
        pos=i;
        memset(a,'\0',sizeof(a));
        while((nodes+pos)->par!=-1){
            a[k++]=(nodes+pos)->tag;
            pos=(nodes+pos)->par;
        }
        strrev(a);    //翻转字符串
        cout<<(nodes+i)->c<<" "<<(nodes+i)->value<<":"<<a<<endl;
    }
    return 0;
}

执行示例:

相关文章

  • 解决C++ 无法从void 转换为LRESULT的方法详解

    解决C++ 无法从void 转换为LRESULT的方法详解

    本篇文章是对C++中无法从void转换为LRESULT的解决方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 深入分析C++中两个大数相乘结果不正确的问题

    深入分析C++中两个大数相乘结果不正确的问题

    本篇文章是对C++中两个大数相乘结果不正确的问题进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言多媒体框架GStreamer入门和概述

    C语言多媒体框架GStreamer入门和概述

    这篇文章主要介绍了C语言多媒体开源框架GStreamer,本文总结了多媒体框架GStreamer一些基本概念及流程,希望能给使用GStreamer开源库的朋友提供一个借鉴或参考,需要的朋友可以参考下
    2022-07-07
  • C++ cin.get用法案例详解

    C++ cin.get用法案例详解

    这篇文章主要介绍了C++ cin.get用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • c++中for双循环的那些事

    c++中for双循环的那些事

    本人很菜,今天看《C++编程思想》中的一道课后题中说到这样一个问题。修改两层嵌套的for循环的标识符,观察结果变化
    2013-05-05
  • C语言实现斗地主的核心算法

    C语言实现斗地主的核心算法

    本文给大家分享的是使用C语言实现的斗地主游戏的核心算法,主要实现了面向对象设计,洗牌、发牌、判断牌型、比较牌的大小、游戏规则等算法。通过这个斗地主小项目的练习,提高了我的面向对象设计能力,加深了对算法的理解。最近把这些设计和算法分享给大家。
    2015-03-03
  • DLL加载设置相对路径的方法

    DLL加载设置相对路径的方法

    这篇文章给大家介绍了DLL加载设置相对路径的方法,非常不错,具有一定的参考借鉴加载,需要的朋友参考下吧
    2018-08-08
  • C++获得本机所有网卡的IP和MAC地址信息的实现方法

    C++获得本机所有网卡的IP和MAC地址信息的实现方法

    下面小编就为大家带来一篇C++获得本机所有网卡的IP和MAC地址信息的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • C++ 详细讲解stack与queue的模拟实现

    C++ 详细讲解stack与queue的模拟实现

    C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,也就是说实现了一个先进后出(FILO)的数据结构,许多程序都使用了 queue 容器。queue 容器可以用来表示超市的结账队列或服务器上等待执行的数据库事务队列
    2022-04-04
  • C++实现趣味扫雷游戏

    C++实现趣味扫雷游戏

    这篇文章主要为大家详细介绍了C++实现趣味扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06

最新评论