赫夫曼树编码的算法及应用习题--数据结构
生活随笔
收集整理的這篇文章主要介紹了
赫夫曼树编码的算法及应用习题--数据结构
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?
赫夫曼樹編碼的算法及應(yīng)用習(xí)題
1.構(gòu)造赫夫曼樹的方法
1.根據(jù)給定的n個權(quán)值{w1,w2,---wn},構(gòu)成n棵二叉樹的集合F={T1,T2...,Tn},其中每棵二叉樹中只有一個帶權(quán)為Wi的根結(jié)點(diǎn),其左右子樹為空。
2.在F中選取兩棵根結(jié)點(diǎn)的權(quán)值最小的樹作為左右子樹(一般小左大右)構(gòu)造新的二叉樹,且置新的二叉樹的權(quán)值為兩棵子樹權(quán)值之和。
3.在F中刪除這兩個樹,同時將新樹加入到F中。
4.重復(fù)2、3兩步,直到F中只有一棵樹。
具體實例:
?
?
2.赫夫曼編碼:
編碼:從葉子結(jié)點(diǎn)到根結(jié)點(diǎn)的最短路徑
譯碼:從根結(jié)點(diǎn)到葉子結(jié)點(diǎn)的最短路徑
具體算法實現(xiàn):
/*求赫夫曼編碼。實現(xiàn)算法6.12的程序 */typedef struct{unsigned int weight;unsigned int parent,lchild,rchild;}HTNode,*HuffmanTree; /* 動態(tài)分配數(shù)組存儲赫夫曼樹 */typedef char **HuffmanCode; /* 動態(tài)分配數(shù)組存儲赫夫曼編碼表 */#include<string.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* UINT_MAX ,C中常量INT_MAX和INT_MIN分別表示最大、最小整數(shù)*/#include<stdio.h> int min1(HuffmanTree t,int i){ /* 函數(shù)void select()調(diào)用 求赫夫曼樹中結(jié)點(diǎn)權(quán)值最小的的是哪個二叉樹*/int j,flag; //flag是用來標(biāo)記第幾個結(jié)點(diǎn)unsigned int k=UINT_MAX; /* 取k為不小于可能的值,無符號整型最大值 */for(j=1;j<=i;j++)if(t[j].weight<k&&t[j].parent==0)k=t[j].weight,flag=j;t[flag].parent=1;return flag;}void select(HuffmanTree t,int i,int *s1,int *s2){ /* s1為最小的兩個值中序號小的那個,把它作為左子樹 */int j;*s1=min1(t,i);*s2=min1(t,i);if(*s1>*s2){j=*s1;*s1=*s2;*s2=j;}}void HuffmanCoding(HuffmanTree *HT,HuffmanCode *HC,int *w,int n) /* 算法6.12 */{ /* w存放n個字符的權(quán)值(均>0),構(gòu)造赫夫曼樹HT,并求出n個字符的赫夫曼編碼HC */int m,i,s1,s2,start;unsigned c,f;HuffmanTree p;char *cd; //用來存放字符if(n<=1)return;m=2*n-1;*HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /* 0號單元未用,開辟赫夫曼樹的存儲空間 */for(p=*HT+1,i=1;i<=n;++i,++p,++w){//構(gòu)建n棵帶權(quán)值的葉子結(jié)點(diǎn)(*p).weight=*w;(*p).parent=0;(*p).lchild=0;(*p).rchild=0;}for(;i<=m;++i,++p){//繼續(xù)使接下來要構(gòu)造的赫夫曼樹每個非葉子結(jié)點(diǎn)為空(*p).parent=0; }for(i=n+1;i<=m;++i) /* 建赫夫曼樹 */{ /* 在HT[1~i-1]中選擇parent為0且weight最小的兩個結(jié)點(diǎn),其序號分別為s1和s2 */select(*HT,i-1,&s1,&s2);(*HT)[s1].parent=(*HT)[s2].parent=i; //把i作為一個樹的根結(jié)點(diǎn)(*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個字符編碼的頭指針向量([0]不用) */cd=(char*)malloc(n*sizeof(char)); /* 分配求編碼的工作空間 */cd[n-1]='\0'; /* 編碼結(jié)束符 */for(i=1;i<=n;i++){ /* 逐個字符求赫夫曼編碼 */start=n-1; /* 編碼結(jié)束符位置 */for(c=i,f=(*HT)[i].parent;f!=0;c=f,f=(*HT)[f].parent)/* 從葉子到根逆向求編碼 */if((*HT)[f].lchild==c)cd[--start]='0';elsecd[--start]='1';(*HC)[i]=(char*)malloc((n-start)*sizeof(char));/* 為第i個字符編碼分配空間 */strcpy((*HC)[i],&cd[start]); /* 從cd復(fù)制編碼(串)到HC */}free(cd); /* 釋放工作空間 */}void main(){HuffmanTree HT;HuffmanCode HC;int *w,n,i;printf("請輸入權(quán)值的個數(shù)(>1):");scanf("%d",&n);w=(int*)malloc(n*sizeof(int));printf("請依次輸入%d個權(quán)值(整型):\n",n);for(i=0;i<=n-1;i++)scanf("%d",w+i); //w是個指針為地址,不加&符號printf("赫夫曼編碼為:\n");HuffmanCoding(&HT,&HC,w,n);for(i=1;i<=n;i++){printf("%d\t",i);puts(HC[i]);}}歡迎關(guān)注,更多博文請瀏覽本人其他文章。
總結(jié)
以上是生活随笔為你收集整理的赫夫曼树编码的算法及应用习题--数据结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 课程设计-毕业设计-JAVA画板课程设计
- 下一篇: 消息中间件那些事--RabbitMQ