回 帖 发 新 帖 刷新版面

主题:敬请赐教

各位高手:
   赫夫曼编码怎么用程序代码实现啊?初学数据结构真的感觉很茫然,可以说说你们的经验吗?望各位不吝赐教,感激不尽![em12]

回复列表 (共2个回复)

沙发

初学数据结构就学到huffman啦。。。?

代码网上一堆,搜搜就有了。

板凳

//望你兴叹
/*编辑器devcpp*/

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

typedef struct
{
    unsigned int weight;/*放权值*/ 
    unsigned int parent;/*父亲结点*/ 
    unsigned int lchild;/*左孩子*/ 
    unsigned int rchild;/*右孩子*/ 
}HTNode, *HuffmanTree;   /*动态申请赫夫曼树*/ 
typedef char **HuffmanCode;/*动态分配赫夫曼表*/ 

void CreateHuffmanTree(HuffmanTree *HT, unsigned int *w , int n);
void Select(HuffmanTree HT, int t, int *s1, int *s2);
void HuffmanCoding(HuffmanTree HT, HuffmanCode *HC, int n);
void PrintHuffmanCode(HuffmanCode HC, unsigned int *w, int n);
int main(void)
{
    HuffmanTree HT; 
    HuffmanCode HC;   
    int i, n;
    unsigned int *w;
    
    printf("请输入叶子结点数 : ");
    scanf("%d", &n);
    
    w = (unsigned int *)malloc(n * sizeof(unsigned int));
    
    printf("请输入各个叶子结点的权值 : \n");
    for(i = 0; i < n; i++)
    {
        scanf("%d", &w[i]);
    }
    CreateHuffmanTree(&HT, w, n);
    HuffmanCoding(HT, &HC, n);
    PrintHuffmanCode(HC, w, n);
    
    getch();
}

/*****************************
建立赫夫曼树,w存放权值,在每次
把两个小的权值相加后,在每次
select中都能包括进去新的结点
每次父亲结点被重新赋值,不为0
在每次select中除去
*****************************/ 
void CreateHuffmanTree(HuffmanTree *HT, unsigned int *w , int n)
{
     int i, m;
     int s1, s2;
     char *cd;
     
     m = 2 * n - 1;                /*总结点数*/
     
     *HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));
     
     for(i = 1; i <= n; ++i, ++w)  /*叶子结点初试化*/ 
     {
         (*HT)[i].weight = *w;
         (*HT)[i].parent = 0;
         (*HT)[i].lchild = 0;
         (*HT)[i].rchild = 0;
     }
     
     for(; i <= m; ++i)
     {
         (*HT)[i].weight = 0;
         (*HT)[i].parent = 0;
         (*HT)[i].lchild = 0;
         (*HT)[i].rchild = 0;
     }
     
     for(i = n + 1; i <= m; ++i)
     {
         Select(*HT, i - 1, &s1, &s2);/*从权值中选两个最小的*/ 
         (*HT)[s1].parent = i;       /*父亲结点都被赋值,在select循环中可以除去*/ 
         (*HT)[s2].parent = i;
         (*HT)[i].lchild = s1;      /*孩子结点被赋值*/ 
         (*HT)[i].rchild = s2;
         (*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;/*加后成新结点*/ 
     }
}

/*寻找两个最小的结点s1, s2*/ 
void Select(HuffmanTree HT, int t, int *s1, int *s2)
{
     int m, n, i;
     
     m = n = 10000;/*感觉有点取巧可以自己修改*/ 
     for(i = 1; i <= t; i++)/*遍历找两个最小的结点*/ 
     {
         if(HT[i].parent == 0 /*m和n只是一个穿插的过程*/ 
            && (HT[i].weight < m || HT[i].weight < n))
         {
             if(m < n)         /*把大的除去,小的继续比较放那里*/ 
             {
                 n = HT[i].weight;
                 *s2 = i;
             }
             else
             {
                 m = HT[i].weight;
                 *s1 = i;
             }
         }
     }
     if(*s1 > *s2)            /*把小的放前面*/
     {
         i = *s1;
         *s1 = *s2;
         *s2 = i;
     }
}

/*赫夫曼编码,放入HC中*/ 
void HuffmanCoding(HuffmanTree HT, HuffmanCode *HC, int n)
{
     int i, start, c, f;
     char *cd;
     
     (*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';
             }//if
             else
             {
                 cd[--start] = '1';
             }//else
         }//for
         
         /*为第i个叶子结点求空间*/ 
         (*HC)[i] = (char *)malloc((n - start) * sizeof(char));
         strcpy((*HC)[i], &cd[start]);     /*从cd复制到HC*/ 
     }//for


/*打印编码*/    
void PrintHuffmanCode(HuffmanCode HC, unsigned int *w, int n)
{
     int i;
     
     printf("HuffmanCode 是 : \n");
     for(i = 1; i <= n; i++)
     {
         printf("%3d---", w[i - 1]);        /*先打印权值*/ 
         puts(HC[i]);                       /*打印表*/ 
         printf("\n");
     }
}
            
          
    
    
    
    


          
    
    
    
    


我来回复

您尚未登录,请登录后再回复。点此登录或注册