[セットトップ]Huffmanコード実装

3481 ワード

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

typedef unsigned int u32;
typedef int status;

#define OK    1
#define ERROR 0
#define N 4
#define UINT_MAX 65535

/* huffman          ,                    */
struct htnode
{
    u32 weight;
#if 0 
    struct htnode *lchild;
    struct htnode *rchild;  
    sturct htnode *father;
#endif
    int lchild;
    int rchild;
    int father; 
};

void select(struct htnode *HT , int n, int *s1, int *s2) 
{
    int i;
    u32 weight = UINT_MAX;
    
    for (i = 1; i <= n; i++)
    {
        if ((HT[i].father == 0) && (HT[i].weight < weight))
        {
            weight = HT[i].weight;
            (*s1) = i;
        }
    }

    weight = UINT_MAX;

    for (i = 1; i <= n; i++)
    {
        if (i == (*s1))
        {
            continue;
        }

        if ((HT[i].father == 0) && (HT[i].weight < weight))
        {
            weight = HT[i].weight;
            (*s2) = i;
        }

    }
}

/*   n+1   ,      n 。 0                 */
status huffman_code(struct htnode **HT, char ***hc, int *w, int n)
{
    int i;
    int m;
    int s1,s2;
    int c,f;
    char *cd;
    int start;
    
    m = 2 * n - 1;

    (*HT) = (struct htnode*)malloc(sizeof(struct htnode) * (m + 1));
    if (!(*HT))
    {
        printf("%s: malloc failed
", __FUNCTION__); return ERROR; } for (i = 1; i <= n; i++) { (*HT)[i].weight = w[i]; (*HT)[i].lchild = 0; (*HT)[i].rchild = 0; (*HT)[i].father = 0; } for (i = n + 1; i <= m; i++) { (*HT)[i].weight = 0; (*HT)[i].lchild = 0; (*HT)[i].rchild = 0; (*HT)[i].father = 0; } for (i = n + 1; i <= m; i++) { select(*HT, i - 1 , &s1, &s2); printf("s1 = %d, s2 = %d
", s1, s2); (*HT)[s1].father = i; (*HT)[s2].father = i; /* w[s1] + w[s2] */ (*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight; (*HT)[i].lchild = s1; (*HT)[i].rchild = s2; } *hc = (char**) malloc(sizeof(char *) * (n + 1)); if (!(*hc)) { printf("%s: malloc failed
", __FUNCTION__); return ERROR; } /* n n-1, '\0' */ cd = (char*)malloc(sizeof(char) * (n - 1 + 1)); cd[n-1] = '\0'; for (i = 1; i <= n; i++) { start = n-1; for (c = i,f = (*HT)[c].father; f != 0; c = f,f = (*HT)[c].father) { if ((*HT)[f].lchild == c) { cd[--start] = '0'; } else { cd[--start] = '1'; } } /* '\0' */ (*hc)[i] = (char *)malloc(sizeof(char) * (n - 1 - start + 1));
        if (!(*hc)[i])
        {
            printf("%s: malloc failed
", __FUNCTION__); return ERROR; } strcpy((*hc)[i], &cd[start]); } } void print_code(char **HC, int *w, int n) { int i; for (i = 1; i <= n; i++) { printf("the %d char(weight(%d))'s code is %s
", i, w[i], HC[i]); } } int main(void) { struct htnode *HT; char **HC; int n = N; int w[N+1] = {-1, 3, 5, 2, 7}; huffman_code(&HT, &HC, w, n); print_code(HC, w, n); }