huffma编码

哈夫曼编码

  编辑
哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变 字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据 字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。
/************************************* 摘自百科百度******************************************************/
代码实现:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#define INF 0x3f3f3f3f

using namespace std;

typedef struct{
    char ch;
    int data;//频率
    int p,lc,rc;
}Htree,*Hufftree;
typedef char* Huffcode;
int min1_ad,min2_ad;//这两个全局变量,记录最小权值的位置
int m;//m=2*n-1

void select(Hufftree &Ht,int j){
    min1_ad=0,min2_ad=0;//原来写的代码为:int min1_ad=0,min2_ad=0,多了一个int
    int min1=INF,min2=INF;//min1第一小的数、min2第二小的数
    for(int k=0;k<=j;k++){
        if(!Ht[k].p){//如果有父节点,跳过。之前用的while,这会使下面的程序段一直执行,而不跳出
            if(Ht[k].data<min1){
                min2=min1;
                min2_ad=min1_ad;
                min1=Ht[k].data;
                min1_ad=k;
            }
            else if(Ht[k].data<min2){
                //比最小数min1大 ,但是比当前第二小的数大
                min2_ad=k;
                min2=Ht[k].data;
            }
        }
    }

}

void Huffman(Hufftree &Ht,Huffcode Hc[],int frequency[],char str[],int n){
    if (n<1)return ;
    m=2*n-1;//链表总长度
    Ht=(Htree*)malloc((m)*sizeof(Htree));

    for(int i=0;i<n;i++){
        Ht[i].data=frequency[i];
        Ht[i].ch=str[i];
        Ht[i].lc=-1; Ht[i].p=0; Ht[i].rc=-1;
    }//录入数据

    for(int i=n;i<m;i++){
        Ht[i].data=0;
        Ht[i].lc=-1; Ht[i].p=0; Ht[i].rc=-1;
    }//初始化

    for(int i=n;i<m;i++){
        select(Ht,i-1);//找到最小的无父节点的两个数,位置储存在s1,s2
        /*错误原码
        Ht[i].lc=Ht[min1_ad].p;
        Ht[i].rc=Ht[min2_ad].p;*/

        Ht[i].lc=min1_ad;//建立父子关系
        Ht[i].rc=min2_ad;
        Ht[i].data=Ht[min1_ad].data+Ht[min2_ad].data;
        Ht[min1_ad].p=i;
        Ht[min2_ad].p=i;
    }

    int start=0;
    char *cd ;
    cd =(char*)malloc(n*sizeof(char));//储存每个变量的哈夫曼编码
        cd[n-1]='\0';
    for(int i=0;i<n;i++){
        start=n-1;
        for(int c=i,f=Ht[i].p;f!=0;c=f,f=Ht[f].p){//顺着父节点向上倒溯
            if (Ht[f].lc==c)
                cd[--start]='0';
            else
                cd[--start]='1';
            /*if(Ht[f].lc==c){//左孩子为Ht[c]
                cd[start]='0';
                start--;
            }
            else {//右边孩子为Ht[c]
                cd[start]='1';
                start--;
            }*/
        }
        Hc[i]=(char*)malloc((n-start)*sizeof(char));
        //Hc[1]=一个对应的动态数组
        strcpy(Hc[i],&cd[start]);
        //从start开始,而不是cd[0]
    }
    free(cd);
}

int main (){
    int n; cout<<"请输入字符个数:"<<endl;  cin >>n;

    char *str;
    str =(char*)malloc((n)*sizeof(char));
    cout<<"请依次输入字符:"<<endl;
        for(int i=0;i<n;i++)cin>>str[i];
//    for(int i=0;i<n;i++)cout<<str[i]<<" ";
//    cout<<endl;

    int *frequency;
    frequency=(int*)malloc((n)*sizeof(int));
    cout<<"请依次输入字符出现次数:"<<endl;
        for(int i=0;i<n;i++)cin>>frequency[i];
//    for(int i=0;i<n;i++)cout<<frequency[i]<<" ";
//    cout<<endl;

    Hufftree Ht; Huffcode *Hc;
    Hc=(Huffcode*)malloc(n*sizeof(Huffcode));
    Huffman(Ht,Hc,frequency,str,n);
//    for (int i=0;i<(2*n-1);i++)cout<<Ht[i].data<<" ";
//    cout<<endl;
    cout<<"字符 哈夫曼编码"<<endl;
    for(int i=0;i<n;i++)cout<<str[i]<<"     "<<Hc[i]<<endl;

    free(str);free(frequency);free(Ht);free(Hc);
    //释放内存空间
}

运行结果:


(水平所限,如有不对,敬请斧正)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值