n0个带权叶子结点所构成的所有二叉树中,带权路径长度WPL最小的二叉树称为Huffman Tree或最优二叉树。
编码:深林中选取两棵结点的权值最小的子树分别作为左右子树构造一棵新的二叉树。
typedef struct { char ch; unsigned int weight; unsigned int parent, lchild, rchild; }HTNode,*HuffmanTree; typedef char** HuffmanCode;
编码
void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, int n, int* w,char *chars) { int s1, s2; HTNode *p ; int i; int m = 2 * n - 1; HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); for (p = HT+1, i = 1; i <= n; i++, p++, w++,chars++) { p->ch = *chars; p->weight = *w; p->parent = p->lchild = p->rchild = 0; } for (; i <= m; i++, p++) { p->ch='\0'; p->weight = p->lchild = p->rchild = p->parent = 0; } for (i = n + 1; i <= m; i++) { select(HT, i - 1, s1, s2); HT[i].lchild = s1; HT[i].rchild = s2; HT[i].weight = HT[s1].weight + HT[s2].weight; HT[s1].parent = i; HT[s2].parent = i; } HC = (char**)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; for (int f = HT[i].parent, c = i; f != 0; c = f, f = HT[f].parent) { if (HT[f].lchild == c) cd[--start] = '0'; else cd[--start] = '1'; } HC[i] = (char*)malloc(sizeof(char) * (n - start)); strcpy(HC[i],&cd[start]); } free(cd); }
select函数//蛮好
void select(HuffmanTree HT, int n, int& s1, int& s2) { int min1 = INT_MAX; int min2 = INT_MAX; for (int i = 1; i <= n; i++) { if (HT[i].parent == 0) { if (HT[i].weight < min1) { min2=min1; min1=HT[i].weight; s2 = s1; s1 = i; } else if (HT[i].weight < min2) { min2=HT[i].weight; s2 = i; } } } }
解码
char* Decoding(HuffmanTree HT, int m, char* buff) { char decode[100]={'\0'}; int i=0; int p = m; while (*buff != '\0') { if (*buff == '0') p = HT[p].lchild; else p = HT[p].rchild; buff++; if (!HT[p].lchild && !HT[p].rchild) { decode[i]=HT[p].ch; i++; p=m; } } decode[i]='\0'; return decode; }