#define MAX_WEIGHT 255
typedef struct
{
int weight;
int traverseMark;
int parent, lchild, rchild;
}HTNode, *HuffmanTree;
typedef char ** HuffmanCode;
HuffmanTree HT = nil;
HuffmanCode HC = nil;
int *markSelect = nil;
int min1 = 0;
int min2 = 0;
void HTselect(int length)
{
int min = MAX_WEIGHT;
for (int i = 0; i < length; i++)
{
if ((HT[i].weight < min)&&(markSelect[i] == 0))
{
min = HT[i].weight;
min1 = i;
}
}
markSelect[min1] = 1;
min = MAX_WEIGHT;
for (int i = 0; i < length; i++)
{
if ((HT[i].weight < min)&&(markSelect[i] == 0))
{
min = HT[i].weight;
min2 = i;
}
}
markSelect[min2] = 1;
return;
}
void HuffmanCoding(int *w, int n)
{
if (n <= 1)
{
return;
}
int m = 2*n - 1;
HT = (HuffmanTree)malloc(m * sizeof(HTNode));
//used in HTSelect for marking the traversed node;
markSelect = (int *)malloc(m * sizeof(int));
for (int q = 0; q < m; q++)
{
markSelect[q] = 0;
}
//init the node weight and status
HuffmanTree p = HT;
int i = 0;
for (;i < n; ++i, ++p)
{
p->weight = w[i];
p->parent = MAX_WEIGHT;
p->lchild = MAX_WEIGHT;
p->rchild = MAX_WEIGHT;
p->traverseMark = 0;
}
for (; i < m; ++i, ++p)
{
p->weight = 0;
p->parent = MAX_WEIGHT;
p->lchild = MAX_WEIGHT;
p->rchild = MAX_WEIGHT;
p->traverseMark = 0;
}
//constuct the Huffman tree
//1...n is leaf nodes
//n+1....m is not leaf nodes
for (int j = n; j < m; j++)
{
HTselect(j);
//
HT[min1].parent = j;
HT[min2].parent = j;
HT[j].lchild = min1;
HT[j].rchild = min2;
HT[j].weight = HT[min1].weight + HT[min2].weight;
}
//print the Huffman tree
p = HT;
for (int j = 0; j < m; p++, j++)
{
NSLog(@"%d, %d, %d, %d", p->weight, p->parent, p->lchild, p->rchild);
}
}
//get the Huffman code from the Huffman root to the leaf
void HuffmanGetCode(int n)
{
int p = 2*n - 1 - 1;
HC = (HuffmanCode)malloc(n * sizeof(char *));
char *cd = (char *)malloc(n * sizeof(char));
int cdlen = 0;
while (p != MAX_WEIGHT)
{
if (HT[p].traverseMark == 0)
{
HT[p].traverseMark = 1;
if (HT[p].lchild != MAX_WEIGHT)
{
p = HT[p].lchild;
cd[cdlen++] = '0';
}
else {
HC[p] = (char *)malloc((cdlen + 1) *sizeof(char));
cd[cdlen] = '\0';
strcpy(HC[p], cd);
}
}
else if (HT[p].traverseMark == 1)
{
HT[p].traverseMark = 2;
if (HT[p].rchild != MAX_WEIGHT)
{
p = HT[p].rchild;
cd[cdlen++] = '1';
}
}
else
{
cdlen--;
HT[p].traverseMark = 0;
p = HT[p].parent;
}
}
for (int i = 0; i < n; i++)
{
printf("%s\n", HC[i]);
}
}
//decode the information using the Huffman tree
void HTDecode(int *code, int elementCount, int n)
{
int i = 0;
int j = 0;
int p = 2*elementCount - 1 - 1;
int decode[MAX_WEIGHT];
while (i < n)
{
if (code[i] == 0)
{
if (HT[p].lchild != MAX_WEIGHT)
{
i++;
p = HT[p].lchild;
}
else
{
decode[j++] = p;
p = 2*elementCount - 1 - 1;
}
}
else
{
if (HT[p].rchild != MAX_WEIGHT)
{
i++;
p = HT[p].rchild;
}
else
{
decode[j++] = p;
p = 2*elementCount - 1 - 1;
}
}
}
decode[j] = p;
for(int i = 0; i <= j; i++)
{
printf("%d", decode[i]);
}
}
-(void)main
{
int weight[5] = {4,5,8,9,12};
HuffmanCoding(weight, 5);
HuffmanGetCode(5);
int code[12] = {0,0,1,0,0,0,1,1,1,1,0,1};
HTDecode(code, 5, 12);
}
Huffman编码
最新推荐文章于 2021-05-18 22:26:09 发布