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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

哈夫曼编码器和译码器(完整代码)

發布時間:2023/12/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哈夫曼编码器和译码器(完整代码) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define N 30 //葉子節點最大值 #define M 2*N-1 //所有結點最大值typedef struct{char data;int weight;int parent;int Lchild;int Rchild;int flag; }HTNode,HuffmanTree[M+1]; //0號單元不用//初始化哈夫曼樹 void InitHuffmanTree(HuffmanTree ht,int n) {printf("#提示——(輸入示例a b c d e)請輸入對應葉子節點的字符:\n");for(int i=1;i<=n;i++) //初始化葉子節點{ht[i].data='\0';ht[i].Lchild=0;ht[i].Rchild=0;ht[i].weight=0;ht[i].parent=0;ht[i].flag=0;getchar(); //消除空格 讀取下一次輸入的空格并且消除ht[i].data=getchar();}printf("#提示——(輸入示例12 40 15 8 25)請輸入對應葉子節點的權重:\n");for(i=1;i<=n;i++) //初始化葉子節點{scanf("%d",&ht[i].weight);}int m=2*n-1;//結點總數for(i=n+1;i<=m;i++)//初始化非葉子節點{ht[i].Lchild=0;ht[i].Rchild=0;ht[i].weight=0;ht[i].parent=0;ht[i].flag=0; //判斷是否被刪除} }//選擇最小權值節點下標 int select(HuffmanTree ht,int n)//選擇最小權值的結點下標 {int i,temp,min;for(i=1;i<=n;i++)//設置初始下標和權值{if(ht[i].flag==0){temp=ht[i].weight;//初始權值min=i;break;}}for(i=1;i<=n;i++){if(ht[i].flag==0&&temp>ht[i].weight){temp=ht[i].weight;min=i;}}ht[min].flag=1;return min;}//構建哈夫曼樹 void createHuffmanTree(HuffmanTree ht,int n) {for(int i=n+1;i<=(2*n-1);i++){int s1=select(ht,i-1);//這里i-1int s2=select(ht,i-1);ht[i].weight = ht[s1].weight+ht[s2].weight;ht[s1].parent=i;ht[s2].parent=i;ht[i].Lchild=s1;ht[i].Rchild=s2;} }//獲得編碼(從下往上反向) int GetCode(int A[],HuffmanTree ht, int n) {int length=0,i,j,get;char s[100]; //定義要輸入字符的空間printf("(#提示——輸入示例bbbaddeccbbb)輸入要編碼的字符:\n");getchar();//清除換行符gets(s);int m=strlen(s);for(i=m-1;i>=0;i--)//從后往前處理字符{for(j=1;j<=n;j++){if(s[i]==ht[j].data){get = j; //獲取最后一個字符的flag也就是位置}}while(ht[get].parent) {if(ht[ht[get].parent].Lchild==get) //判斷父節點的左孩子是否等于我們找的get那個位置{A[length]=0; //左孩子是0}else{A[length]=1; //右孩子是1}length++;get=ht[get].parent;//再把父節點給get 直到父節點為0 就編碼成功}}return length-1; //最后會多+1,所以減去一個1 }//打印編碼 void printCode(int A[], int length) {int i;for(i=length; i>=0; i--)//從后向前輸出即為編碼結果{printf("%d",A[i]);}printf("\n"); }//解碼 int GetreCode(int A[], char B[], HuffmanTree ht, int length1, int n) {int i,length2=0,cur=2*n-1;for(i=length1;i>=0;i--){if(A[i])//A[i]只可能為1或者0,提示:0是左孩子,1是右孩子{cur=ht[cur].Rchild;//根結點的右孩子賦值給curif(ht[cur].Rchild==0)//該結點的右孩子如果是0就說明是葉子節點,提示:二叉樹只有0和2{B[length2]=ht[cur].data;length2++;cur=2*n-1;//回到根節點}}else{cur=ht[cur].Lchild;//和上面一樣就不說了if(ht[cur].Lchild==0){B[length2]=ht[cur].data;length2++;cur=2*n-1;}}}return length2-1; }//解碼打印 void printreCode(char B[],int length2) {int i;for(i=0;i<=length2;i++)printf("%c",B[i]);printf("\n"); }//打印哈夫曼樹 void printHuffmanTree(HuffmanTree ht, int n) {printf("結點\tweigt\tdata\tLchild\tRchild\tparent\n");for(int i=1;i<=n;i++){printf("%d\t%d\t%c\t%d\t%d\t%d\n",i,ht[i].weight,ht[i].data,ht[i].Lchild,ht[i].Rchild,ht[i].parent);} }int main() {HuffmanTree ht; int n; //n為所需的結點數int A[100];//存儲編碼char B[100];//存儲輸出的字符串printf("#提示——(輸入示例 5)請輸入葉子節點個數:\n");scanf("%d",&n);InitHuffmanTree(ht,n); //初始化createHuffmanTree(ht,n); //構建哈弗曼樹int length = GetCode(A,ht,n);printCode(A,length);int length2 = GetreCode(A,B,ht,length,n);printreCode(B,length2);printHuffmanTree(ht,n); }

總結

以上是生活随笔為你收集整理的哈夫曼编码器和译码器(完整代码)的全部內容,希望文章能夠幫你解決所遇到的問題。

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