赫夫曼树
#include <conio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct{ int weight; int parent, lchild,rchild; }HTNode, *HuffmanTree; typedef char ** HuffmanCode; void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n); //w存放n个字符的权值,构造赫夫曼书HT,并求出n个字符的赫夫曼编码HC void select(const HuffmanTree &HT, int n, int &s1, int &s2); //选择parent为0且weiht最小的两个结点,其序号分别为s1,s2 int main(){ HuffmanTree HT; HuffmanCode HC; int i; const int n = 8; int weight[n] = {5,29,7,8,14,23,3,11}; HuffmanCoding(HT, HC, weight, n); for(i=1; i<=n; i++) printf("%d %s\n",HT[i].weight, HC[i]); return 0; } void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n){ //w存放n个字符的权值,构造赫夫曼书HT,并求出n个字符的赫夫曼编码HC int i,m,s1,s2; // HuffmanTree p; int start,f,c;//start指向当前编码位置,f为parent结点序号,c为当前的结点序号 if(n <= 1) return ; m = 2*n-1; HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); //0号单元未用 memset(HT,0,(m+1)*sizeof(HTNode)); for(i=1; i<=n; ++i, ++w) HT[i].weight = *w; for(i = n+1; i<=m; i++){ //建赫夫曼树 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; } //求赫夫曼编码 HC = (HuffmanCode)malloc((n+1) * sizeof(char *)); //分配n个字符编码的头指针向量 char *cd = (char *)malloc(n * sizeof(char)); //分配求编码的工作空间 cd[n-1] = '\0';//编码结束符 for(i=1; i<=n; i++){ //逐个字符求赫夫曼编码 start = n-1;//编码结束符位置 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)); //为第i个字符编码分配空间 strcpy(HC[i], &cd[start]); //从cd复制编码到HC } free(cd); } void select(const HuffmanTree &HT, int n, int &s1, int &s2){ //选择parent为0且weiht最小的两个结点,其序号分别为s1,s2 if(n < 1) return ; int i,min1,min2; //min1为最小,min2为第二小 int ic=0; //主要用来处理初始时的情况 和 当!=0 的数仅剩2个的情况 for(i=1; i<=n; i++){ if(HT[i].parent != 0) continue; if(ic == 0){ min1 = i; min2 = i; ic++; } else if(ic == 1){ if(HT[min1].weight > HT[i].weight){ min2 = min1; min1 = i; ic++; } else{ min2 = i; ic++; } } else{ if(HT[min1].weight > HT[i].weight){ min2 = min1; min1 = i; } else if(HT[min2].weight > HT[i].weight) min2= i; else if(HT[min2].weight == HT[i].weight && min1 == min2) min2 = i; } } s1 = min1; s2 = min2; }