在普通的数据创作的书,在树的章,作者引见霍夫曼(霍夫曼)

树和霍夫曼编码。哈夫曼编码是哈夫曼树的单独申请。霍夫曼编码是普遍的运用的,如

JPEG编码打中申请霍夫曼。 率先引见是什么哈夫曼树。哈夫曼树也叫最优二叉树,

是最短方法树的额外的程度2。。相同的树的带权方法程度,树中持有叶结节

的分量乘以根结节 方法程度(根结节是0免得层,页结节到根结节的方法程度

说起叶结节数)。额外的方法程度记为WPL (W1*L1+W2*L2+W3*L3+…+Wn*Ln)

,n重Wi(I = 1,2,n n)调解单独树的叶结节的二叉树,相关联的的叶结节的方法

李的程度(I = 1,2,…n)。可以检定哈夫曼树的WPL是最小的。

霍夫曼编码的快速地流动:

一、说起单独事先调整的量N { W1,W2,W3,…,Wi,…,WN }调解的初始集F n树,两树 { T1,T2,T3,…,Ti,…,Tn},单独的单独根结节,在每两个分岔的TR重Wi,左、右子树为空。(在电脑上赚得的适当的 法,普通命令是升序排列的钛量Wi。)
二、F,选择两个树的根结节的树的最小分量为单独新的,和分量的新的二叉树的根结节为根的分量。
三、从F中截这两棵树,在升阶F组添加新的两棵树。。
四、反复快速地流动32和两,直到有单独二叉树集中打中F。

简略领会执意,免得我有单独,B,C,D,E五印,频率(分量)为5。,4,3,2,1,我们的的第一步是把两个最小分量的左、右subtre,即以1,2单独新的树,结节是1 2 = 3,如图:

12

虚线是一家新使成为的结,子孙的重次要的步3其他的结节,因而设置为{ 5,4,3,3},阵地次要的步,把两个新树的最小分量,如图:

13

再转移创作零件哈夫曼树,如下图:

14

每个印的分量相关联的的交换:

15

因而每个印对应的编码:A->11,B->10,C->00,D->011,E->010

霍夫曼是单独无前缀编码的编码。不要污迹解码。它次要用于数据压缩,编密码和解密。。

C言语指定遗传密码:

/*-------------------------------------------------------------------------
 * Name:   Huffman encoding source code。
 * Date:   
 * Author: Jeffrey Hill+Jezze(解码部门)
 * 在 Win-TC 下尺寸经过
 * 赚得快速地流动:着先经过 HuffmanTree() 职务创作零件哈夫曼树,那时在主职务 主(中)
 *           从使固定开端(即从零开端断定结节排列,若在
 *           父硬块左手,的指定遗传密码 0,免得在精密的,的指定遗传密码 1。终极出口编码发生的。
 *------------------------------------------------------------------------*/
#include 
#include
 
#define MAXBIT      100
#define MAXVALUE  10000
#define MAXLEAF     30
#define MAXNODE    MAXLEAF*2 -1
 
typedef struct
{
int bit[MAXBIT];
int start;
} HCodeType;        /* 编码创作体 */
typedef struct
{
int weight;
int parent;
int lchild;
int rchild;
intvalue;
} HNodeType;        /* 硬块创作体 */
 
/* 创作零件一颗哈夫曼树 */
void HuffmanTree (HNodeType HuffNode[MAXNODE],  int n)
{ 
/* i、j: 使翻筋斗变量,m1、m2:创作零件哈夫曼树清楚的快速地流动中两个最小使变重硬块的使变重,
        x1、x2:创作零件哈夫曼树清楚的快速地流动中两个最小使变重硬块在排列打中序号。*/
int i, j, m1, m2, x1, x2;
/* 设定初值存款哈夫曼树排列 HuffNode[] 的结节 */
for (i=0; i<2*n-1; i++)
    {
        huffnode [我]。分量 = 0;//使变重 
        huffnode [我]。母 =-1;
        huffnode摆布[我]。 =-1;
        HuffNode[i].rchild =-1;
        HuffNode[i].value=i; //实践值,可阵地保持健康发音法母替代  
    } /* end for */
 
/* 输出 n 单独叶结节的分量 */
for (i=0; i
    {
        printf ("Please input weight of leaf node %d: \n", i);
        scanf ("%d", &huffnode [我]。分量);
    } /* end for */
 
/* 使翻筋斗创作零件 Huffman 树 */
for (i=0; i
    {
        m1=m2=MAXVALUE;     /* m1、M2往事在两个无父结节和两个分量最小的结节 */
        x1=x2=0;
/* 发现时持有硬块的使变重最小的、无少许两个结节的父结节,使接缝平滑成单独二叉树 */
for (j=0; j
        {
if (huffnode [J]。分量 < m1 && HuffNode[j].parent==-1)
            {
                m2=m1; 
                x2=x1; 
                M1 = huffnode [J]。分量
                x1=j;
            }
elseif (huffnode [J]。分量 < m2 && HuffNode[j].parent==-1)
            {
                M2 = huffnode [J]。分量
                x2=j;
            }
        } /* end for */
/* 找到两开发结节。 x1、x2 父结节传达 */
        huffnode [ 1 ]。母  = n+i;
        huffnode [ 2 ]。母  = n+i;
        HuffNode[n+i].weight = huffnode [ 1 ]。分量 + huffnode [ 2 ]。分量
        HuffNode[n+i].lchild = x1;
        HuffNode[n+i].rchild = x2;
 
        printf ("x1.weight and x2.weight in round %d: %d, %d\n", i+1, huffnode [ 1 ]。分量, huffnode [ 2 ]分量)。  /* 尺寸 */
        printf ("\n");
    } /* end for */
/*  为(i = 0;我
    {
        printf( 家长:%d,摆布:%d,rchild:%d,诉讼费:%d,weight:%d\n",huffnode [我]。母,huffnode摆布[我]。,HuffNode[i].rchild,huffnode [我]的诉讼费。,huffnode [我]。分量);
                  }*///尺寸 
} /* end HuffmanTree */
 
//解码 
void decodeing(charstring[],HNodeType Buf[],int 努姆)
{
int i,tmp=0,code[1024];
int m=2*Num-1;
char *nump;
char num[1024];
for(i=0;istring);i++)
  {
if(string[i]==''0'')
  num[i]=0;        
else
  num[i]=1;                    
  } 
  i=0;
  nump=&num[0];

while(nump<(&num[strlen(string)]))
 {tmp=m-1;
while((BUF [ TMP摆布]。!1)&&(BUF [ ] rchild TMP。!=-1))
  {

if(*nump==0)
   {
     TMP = buf [ TMP摆布]。 ;          
   } 
else tmp=但[ TMP ]rchild;
   nump++;

  } 

  printf("%d",但[ TMP ]value);                                  
 }
 

}
 
 
int main(void)
{

    HNodeType HuffNode[MAXNODE];            /* 单独结节的创作排列的精确地解释 */
    HCodeType HuffCode[MAXLEAF],  cd;       /* 精确地解释排列创作编码, 同时,单独暂时变量的精确地解释往事印制的广告 */
int i, j, c, p, n;
char PP [ 100 ]
    printf ("Please input n:\n");
    scanf ("%d", &n);
    HuffmanTree (HuffNode, n);


for (i=0; i < n; i++)
    {
         = n-1;
        c = i;
        p = HuffNode [ C ]。母
while (p != -1)   /* 父结节的在 */
        {
if (HuffNode [P]摆布。 == c)
                [] = 0;
else
                [] = 1;
            --;        /* 下一位编码 */
            c=p;                    
            p=HuffNode [ C ]。母    /* 设置下单独使翻筋斗授权 */
        } /* end while */

/* 霍夫曼编码,对每个叶结节牧草的编码 */
for (j=+1; j
        { huffcode [我],点[ J ] = [j];}
        huffcode [我]开端 = ;
    } /* end for */

/* 牧草持有目前的的编码霍夫曼编码出口。 */
for (i=0; i
    {
        printf ("%d ''s Huffman code is: ", i);
for (j=huffcode [我]开端+1; j < n; j++)
        {
            printf ("%d", huffcode [我],点[ J ]);
        }
        printf(" 开端:%d,huffcode [我]开端);

        printf ("\n");

    }
/*    为(i = 0;我
    (J = 0;J为
        {
             printf ("%d", huffcode [我],点[ J ]);           
        }
        printf(\n");
        }*/
    printf(解码?委托 Enter 指定遗传密码:n);
    scanf("%s",PP)
decodeing(pp,HuffNode,n);
    getch();
return 0;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注