赫夫曼樹和赫夫曼編碼


什么是哈夫曼樹

當用 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();

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM