霍夫曼编码

http://blog.csdn.net/World7th/archive/2007/03/20/1535452.aspx







附代码

#include  < stdio.h >
#include 
< string .h >
#include 
< stdlib.h >
#include 
< malloc.h >
#include 
< conio.h >

typedef 
struct   {
    unsigned 
int weight;        //当前结点的权值
    unsigned int parent;        //当前结点的父结点的下标,为0时表示无父结点
    unsigned int lchild, rchild;    //当前结点的左,右孩子结点的下标,为0时表示无孩子结点
}
 HTNode, * HuffmanTree;

typedef 
char   ** HuffmanCode;

typedef 
struct   {
    unsigned 
int s1;
    unsigned 
int s2;
}
 MinCode;

void  Error( char   * message);
HuffmanCode HuffmanCoding(HuffmanTree HT,HuffmanCode HC,unsigned 
int   * w,unsigned  int  n);
MinCode Select(HuffmanTree HT,unsigned 
int  n);

/**/ /* 错误处理 */
void  Error( char   * message)
{
    system(
"CLS");                //清除屏幕缓冲区及液晶显示缓冲区, 光标位置回到屏幕左上角。ClearScreen
    
//clrscr();
    fprintf(stderr,"Error:%s\n",message);        //stderr标准错误流, 一般把屏幕设为默认
    exit(1);
}



HuffmanCode HuffmanCoding(HuffmanTree HT,HuffmanCode HC,unsigned 
int   * w,unsigned  int  n)
{
    unsigned 
int i,s1=0,s2=0;
    HuffmanTree p;
    
char *cd;
    unsigned 
int f,c,start,m;
    MinCode min;
    
if(n<=1) Error("Code too small!");
        m
=2*n-1;
    HT
=(HuffmanTree)malloc((m+1)*sizeof(HTNode));        //m+1个空间
    for(p=HT,i=0;i<=n;i++,p++,w++)
    
{
        p
->weight=*w;
        p
->parent=0;
        p
->lchild=0;
        p
->rchild=0;
    }

    
for(;i<=m;i++,p++)
    
{
        p
->weight=0;
        p
->parent=0;
        p
->lchild=0;
        p
->rchild=0;
    }

    
for(i=n+1;i<=m;i++)
    
{
        min
=Select(HT,i-1);
        s1
=min.s1;
        s2
=min.s2;
        HT[s1].parent
=i;
        HT[s2].parent
=i;
        HT[i].lchild
=s1;
        HT[i].rchild
=s2;
        HT[i].weight
=HT[s1].weight+HT[s2].weight;
    }

    printf(
"HT List:\n");
    printf(
"Number\t\tweight\t\tparent\t\tlchild\t\trchild\n");
    
for(i=1;i<=m;i++)
        printf(
"%d\t\t%d\t\t%d\t\t%d\t\t%d\n",
        HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
    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)
            
if(HT[f].lchild==c) cd[--start]='0';
            
else cd[--start]='1';
        HC[i]
=(char *)malloc((n-start)*sizeof(char *));
        strcpy(HC[i],
&cd[start]);
    }

    free(cd);
    
return HC;
}


MinCode Select(HuffmanTree HT,unsigned 
int  n)
{
    unsigned 
int min,secmin;
    unsigned 
int temp;
    unsigned 
int i,s1,s2,tempi;
    MinCode code;
    s1
=1;s2=1;
    
for(i=1;i<=n;i++)
        
if(HT[i].parent==0)
        
{
            min
=HT[i].weight;
            s1
=i;
            
break;
        }

    tempi
=i++;
    
for(;i<=n;i++)
        
if(HT[i].weight<min&&HT[i].parent==0)
        
{
            min
=HT[i].weight;
            s1
=i;
        }

    
for(i=tempi;i<=n;i++)
        
if(HT[i].parent==0&&i!=s1)
        
{
            secmin
=HT[i].weight;
            s2
=i;
            
break;
        }

    
for(i=1;i<=n;i++)
        
if(HT[i].weight<secmin&&i!=s1&&HT[i].parent==0)
        
{
            secmin
=HT[i].weight;
            s2
=i;
        }

    
if(s1>s2)
    
{
        temp
=s1;
        s1
=s2;
        s2
=temp;
    }

    code.s1
=s1;
    code.s2
=s2;
    
return code;
}


void  main()
{
    HuffmanTree HT
=NULL;        //Huffman指针
    HuffmanCode HC=NULL;        //
    unsigned int *w=NULL;
    unsigned 
int i,n;
    
char ch;
    system(
"CLS");
 
//clrscr();
    printf("Input n:\n");
    scanf(
"%d",&n);
    w
=(unsigned int *)malloc((n+1)*sizeof(unsigned int *));        //为w提供n+1个unsigned int空间,即w可以存放n+1个值,值为w[0]到w[n]
    w[0]=0;
    printf(
"Enter weight:\n");
    
for(i=1;i<=n;i++)
    
{
        printf(
"w[%d]=",i);
        scanf(
"%d",&w[i]);
    }

    HC
=HuffmanCoding(HT,HC,w,n);
    printf(
"HuffmanCode:\n");
    printf(
"Number\t\tWeight\t\tCode\n");
    
for(i=1;i<=n;i++)
        printf(
"%d\t\t%d\t\t%s\n",i,w[i],HC[i]);

}

你可能感兴趣的:(霍夫曼编码)