赫夫曼树和赫夫曼编码

Posted xiaoqiz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了赫夫曼树和赫夫曼编码相关的知识,希望对你有一定的参考价值。

什么是哈夫曼树

当用 n 个结点(都做叶子结点且都有各自的权值)试图构建一棵树时,如果构建的这棵树的带权路径长度最小,称这棵树为“最优二叉树”,有时也叫“赫夫曼树”或者“哈夫曼树”。

在构建哈弗曼树时,要使树的带权路径长度最小,只需要遵循一个原则,那就是:权重越大的结点离树根越近。在图 1 中,因为结点 a 的权值最大,所以理应直接作为根结点的孩子结点。

技术图片     技术图片

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include<limits.h>
typedef struct{
    unsigned int weight;
    unsigned int parent,lchild,rchild;
}htnode,*huffmantree;  // 赫夫曼树的结构类型

typedef char **huffmancode;

int min(huffmantree t, int i){
    int j,flag;
    unsigned int k=UINT_MAX;
    for(j=1;j<=i;j++){
        if(t[j].weight<k&&t[j].parent==0){
        k=t[j].weight;  flag=j;
        }
    }
        t[flag].parent=1;
        return flag;
}
void select(huffmantree t,int i,int &s1,int &s2){
    int j;
    s1=min(t,i);
    s2=min(t,i);
    if(s1>s2){
    j=s1;  s1=s2;  s2=j;
    }
}
void huffmancoding(huffmantree &ht,huffmancode &hc,int *w,int n){
    int m,i,s1,s2,start;
    unsigned int c,f;
    huffmantree p;
    char *cd=NULL;

    m=2*n-1;
    ht=(huffmantree)malloc((m+1)*sizeof(htnode));  // m+1表示0号单元不用
    for(p=ht+1,i=1;i<=n;i++,p++){
        p->weight=w[i-1];  p->parent=0; p->lchild=0; p->rchild=0;
    }
    for(;i<=m;i++,p++){   
        p->parent=0;
    }
    for(i=n+1;i<=m;i++){   //建立赫夫曼树
        select(ht,i-1,s1,s2);
        ht[s1].parent=ht[s2].parent=i;
        ht[i].lchild=s1;  ht[i].rchild=s2;
        ht[i].weight=ht[s1].weight+ht[s2].weight;
    }

    hc=(huffmancode)malloc((n+1)*sizeof(char *));
    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){
         // 一直循环知道最后一个没有双亲的结点,用f来寻找父母往上走
            if(ht[f].lchild==c)  cd[--start]=0;
            else   cd[--start]=1; //这里分支语句用来判断在左还是右,编码0和1
        }    //n-1位置已经存放了‘/0‘,所以用--start,从n-2存放0,1编码
        hc[i]=(char *)malloc((n-start)*sizeof(char));
        strcpy(hc[i],&cd[start]);
    }
    free(cd);
}


int main(){
    huffmantree ht=NULL;  // 二级指针
    huffmancode hc;
    int *w,n,i;
    printf("Please input the number of all the node digit:");
    scanf("%d",&n);
    w=(int *)malloc(n*sizeof(int));
    printf("Please input the %d node digits:\n",n);
    for(i=0;i<n;i++){
    scanf("%d",w+i);
    }
    huffmancoding(ht,hc,w,n);
    for(i=1;i<=n;i++){
    puts(hc[i]);}
    getch();

}

 

以上是关于赫夫曼树和赫夫曼编码的主要内容,如果未能解决你的问题,请参考以下文章

哈夫曼树和哈夫曼编码

贪心算法之哈夫曼树和哈夫曼编码

赫夫曼树和赫夫曼编码

数据结构—— 树:哈夫曼树和哈夫曼编码

哈夫曼树和哈夫曼编码

哈夫曼(Huffman)树和哈夫曼编码