参照书上写的Huffman树的代码 结构用的是线性存储的结构 不是二叉链表 里面要用到查找最小和第二小 理论上锦标赛法比较好 但是实现好麻烦啊
考虑到数据量不是很大 就直接用比较笨的先找最小 去掉最小再找第二小的方法了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct{
unsigned int weight;
unsigned int parent, lchild, rchild;
}HTNode, *HuffmanTree;typedef char ** HuffmanCode;
int Select(HuffmanTree HT, int n, int &s1, int &s2)
{
if(n <= 1) return 1;
else
{
int i;
s1 = 0; s2 = 0;
for(i = 1; i <= n; i++)
{
if(s1 == 0 && HT[i].parent == 0)
{
s1 = i;
}
else if(HT[i].parent == 0 && HT[i].weight < HT[s1].weight && s1 != 0)
{
s1 = i;
}
}
for(i = 1; i <= n; i++)
{
if(i == s1)
{
continue;
}
else if(s2 == 0 && HT[i].parent == 0)
{
s2 = i;
}
else if(HT[i].parent == 0 && HT[i].weight < HT[s2].weight && s2 != 0)
{
s2 = i;
}
}
}
return 0;
}
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int * w, int n)
{
if(n <= 1) return;
int m = 2 * n - 1;
HuffmanTree p;
int i;
HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));
for(p = HT, i = 1; i <= n; i++, p++, w++) //初始化
{
p->weight = *w; p->parent = 0; p->rchild = 0; p->lchild = 0;
}
for( ; i <= m; i++, p++)
{
p->weight = 0; p->parent = 0; p->rchild = 0; p->lchild = 0;
}for(i = n + 1; i <= m; i++) //建Huffman树
{
int s1, s2;
Select(HT, i - 1, s1, s2);
HT[s1].parent = i; HT[s2].parent = i;
HT[i].lchild = s1; HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
HT[i].parent = 0; //不加这句会出错
}HC = (HuffmanCode)malloc((n + 1) * sizeof(char *));
char * cd = (char *)malloc(n * sizeof(char));
cd[n - 1] = ‘\0‘;
for(i = 1; i <= n; i++)
{
int start = n - 1;
int c, f;
for(c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
{
if(HT[f].lchild == c) cd[--start] = ‘0‘;
else{ cd[--start] = ‘1‘;}
}
HC[i] = (char *)malloc((n - start) * sizeof(char));
strcpy(HC[i], &cd[start]);
}
free(cd);
}int main()
{
int N = 10; //一共10个权值
int w[10] = {1,2,3,4,5,6,7,8,9,0};
HuffmanTree HT;
HuffmanCode HC;
HuffmanCoding(HT, HC, w, N);int i, j;
for(i = 1; i <= N; i++)
{
printf("%d: ", i);
for(j = 0; HC[i][j] != ‘\0‘; j++)
{
printf("%c", HC[i][j]);
}
printf("\n");
}return 0;
}
【数据结构】Huffman树