日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

赫夫曼树编码的算法及应用习题--数据结构

發(fā)布時間:2024/7/5 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 赫夫曼树编码的算法及应用习题--数据结构 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

赫夫曼樹編碼的算法及應用習題

1.構造赫夫曼樹的方法

1.根據給定的n個權值{w1,w2,---wn},構成n棵二叉樹的集合F={T1,T2...,Tn},其中每棵二叉樹中只有一個帶權為Wi的根結點,其左右子樹為空。

2.在F中選取兩棵根結點的權值最小的樹作為左右子樹(一般小左大右)構造新的二叉樹,且置新的二叉樹的權值為兩棵子樹權值之和。

3.在F中刪除這兩個樹,同時將新樹加入到F中。

4.重復2、3兩步,直到F中只有一棵樹。

具體實例:

?

?

2.赫夫曼編碼:

編碼:從葉子結點到根結點的最短路徑

譯碼:從根結點到葉子結點的最短路徑

具體算法實現(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()調用 求赫夫曼樹中結點權值最小的的是哪個二叉樹*/int j,flag; //flag是用來標記第幾個結點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個字符的權值(均>0),構造赫夫曼樹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){//構建n棵帶權值的葉子結點(*p).weight=*w;(*p).parent=0;(*p).lchild=0;(*p).rchild=0;}for(;i<=m;++i,++p){//繼續(xù)使接下來要構造的赫夫曼樹每個非葉子結點為空(*p).parent=0; }for(i=n+1;i<=m;++i) /* 建赫夫曼樹 */{ /* 在HT[1~i-1]中選擇parent為0且weight最小的兩個結點,其序號分別為s1和s2 */select(*HT,i-1,&s1,&s2);(*HT)[s1].parent=(*HT)[s2].parent=i; //把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個字符編碼的頭指針向量([0]不用) */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';elsecd[--start]='1';(*HC)[i]=(char*)malloc((n-start)*sizeof(char));/* 為第i個字符編碼分配空間 */strcpy((*HC)[i],&cd[start]); /* 從cd復制編碼(串)到HC */}free(cd); /* 釋放工作空間 */}void main(){HuffmanTree HT;HuffmanCode HC;int *w,n,i;printf("請輸入權值的個數(shù)(>1):");scanf("%d",&n);w=(int*)malloc(n*sizeof(int));printf("請依次輸入%d個權值(整型):\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]);}}

歡迎關注,更多博文請瀏覽本人其他文章。

總結

以上是生活随笔為你收集整理的赫夫曼树编码的算法及应用习题--数据结构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。