【数据结构】Huffman树
参照书上写的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; }