1. 程式人生 > >資料結構與演算法 (七) 哈夫曼樹(Huffman)與哈夫曼編碼

資料結構與演算法 (七) 哈夫曼樹(Huffman)與哈夫曼編碼

1.演算法思想

         哈夫曼樹又稱最優二叉樹,是一種帶權路徑長度最短的二叉樹。所謂樹的帶權路徑長度,就是樹中所有的葉結點的權值乘上其到根結點的路徑長度(若根結點為0層,葉結點到根結點的路徑長度為葉結點的層數)。樹的路徑長度是從樹根到每一結點的路徑長度之和,記為WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N個權值Wi(i=1,2,...n)構成一棵有N個葉結點的二叉樹,相應的葉結點的路徑長度為Li(i=1,2,...n)

2.演算法實現

#include <stdio.h>
#include <stdlib.h>
//最小生成樹  應用 哈夫曼編碼
struct huffmannode
{
    int weight;
    int tag,LeftChild,RightChild;
};

typedef  struct huffmannode Huffmannode;

void InitHuffmannode(Huffmannode *h,int t,int l,int r)
{
    h->tag=t;
    h->LeftChild=l;
    h->RightChild=r;
}
struct huffmantree
{
    int root;
};

typedef struct huffmantree Huffmantree;

void InitHuffmantree(Huffmantree *ht,int r)
{
    ht->root=r;
}
//建立哈夫曼樹
void makeHuffmantree(Huffmantree *ht,int a[],Huffmannode b[],int n)
{
    int i,j,m1,m2,x1,x2;
    //逐步構造 Huffman 樹*/
    for(i=0; i<n; i++)
        b[i].weight=a[i];
    for(i=1; i<n-1; i++)
    {
        m1=m2=32767; //m1, m2 是任何權都大的 整數*/
        x1=x2=-1;

        for(j=0; j<n+i-1; j++)
        {
            if(b[j].weight<m1&&b[j].tag==0)
            {
                m2=m1;
                x2=x1;
                m1=b[j].weight;
                x1=j;
            }
            else if(b[j].weight<m2&&b[j].tag==0)
            {
                m2=b[j].weight;
                x2=j;
            }
        }

        b[x1].tag=1;
        b[x2].tag=1;

        //構造子樹
        b[n-1+i].weight=b[x1].weight+b[x2].weight;
        b[n-1+i].LeftChild=x1;
        b[n-1+i].RightChild=x2;
        b[n-1+i].tag=0;
    }
    ht->root=2*n-2;
}
//哈夫曼編碼就是利用哈夫曼樹生成字首唯一的不等長編碼(從根部開始左子樹是0右子樹為1)
int main()
{
    printf("哈夫曼編碼就是利用哈夫曼樹生成字首唯一的不等長編碼(從根部開始左子樹是0右子樹為 \n");
    return 0;
}