[セットトップ]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);
}