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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

学习日志---哈夫曼树相关算法

發布時間:2025/5/22 编程问答 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学习日志---哈夫曼树相关算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

哈夫曼樹概念:

????如果二叉樹中的葉結點都帶有權值,我們可以把這個定義加以推廣。設二叉樹有n個帶權值的葉結點,定義從二叉樹的根結點到二叉樹中所有葉結點的路徑長度與相應葉結點權值的乘積之和為該二叉樹的帶權路徑長度(WPL),即:

????WPL = 求和(w*li)

????wi為第i個葉結點的權值,li為從根結點到第i個葉結點的路徑長度。?

WPL最小的樹稱為哈夫曼樹。

哈夫曼樹的結點類

//哈夫曼樹的結點類 public?class?HaffNode?{//權值一般值出現的權重,越大則表示出現的越多int?weight;?//權值int?parent?;//雙親int?flag?;//標志int?leftChild;?//左孩子int?rightChild;//右孩子HaffNode(){}}

哈夫曼編碼類

//哈夫曼編碼類 public?class?Code?{//存對應該權值字符的編碼int[]?bit;??//編碼數組//每個字符的編碼長度是一樣的,但開始的位置不同,這里的start指的是從哪里開始。int?start;??//編碼的開始下標int?weight;?//權值Code(int?n){bit?=?new?int[n];start?=?n-1;} }

哈夫曼樹類

哈夫曼樹的所有節點都是放在一個數組中。

//哈夫曼樹類 public?class?HaffmanTree?{//最大權值static?final?int?MAXVALUE=1000;int?nodeNum?;?//葉子結點個數public?HaffmanTree(int?n){//這里傳入有多少個葉子節點this.nodeNum?=?n;}//構造哈夫曼樹算法public?void?haffman(int[]?weight,HaffNode[]?nodes){int?n?=?this.nodeNum;//m1,m2,表示最小的兩個權值,x1,x2,表示最小兩個權值對應的編號int?m1,m2,x1,x2;?//初始化所有的結點,對應有n個葉子結點的哈夫曼樹,有2n-1個結點。for(int?i=0;i?<?2*n-1;i++){HaffNode?temp?=?new?HaffNode();//初始化n個葉子結點if(i?<?n){temp.weight?=?weight[i]; }else{temp.weight?=?0; }temp.parent?=?0;temp.flag?=?0;temp.leftChild?=?-1;temp.rightChild?=?-1;nodes[i]?=?temp;}//初始化n-1個非葉子結點for(int?i=0;i<n-1;i++){//每次出來后對這倆都要歸為最大才能尋找出較小的值m1?=?m2?=?MAXVALUE;x1?=?x2?=0;//這個內層的循環是每次加一個節點,然后尋找總的節點中最小的兩個沒有用過的節點//flag的作用是:0為沒用過,1是以稱為子節點加入樹中//m1是最小值,m2是次小值for(int?j=0;j<?n+i;j++){if(nodes[j].weight<m1?&&?nodes[j].flag==0){m2?=?m1;x2?=?x1;m1?=?nodes[j].weight;x1?=?j;}else?if(nodes[j].weight<m2?&&?nodes[j].flag?==0){m2?=?nodes[j].weight;x2?=?j;}}//每次循環后得到的倆小節點的合節點在n+i位置nodes[x1].parent?=?n+i;nodes[x2].parent?=?n+i;nodes[x1].flag?=?1;nodes[x2].flag?=?1;nodes[n+i].weight?=?nodes[x1].weight?+?nodes[x2].weight;nodes[n+i].leftChild?=?x1;nodes[n+i].rightChild?=?x2;}}//哈弗曼編碼算法public?void?haffmanCode(HaffNode[]?nodes,Code[]?haffCode){int?n?=?this.nodeNum;Code?code?=?new?Code(n);int?child,parent;//對n個葉子節點循環找編碼for(int?i=0;i<n;?i++){//反向添加數組code.start?=?n-1;code.weight?=?nodes[i].weight;child?=?i;parent?=?nodes[child].parent;while(parent!=0){if(nodes[parent].leftChild?==?child){code.bit[code.start]?=?0;}else{code.bit[code.start]?=?1;}code.start--;?child?=?parent;parent?=?nodes[child].parent;}Code?temp?=?new?Code(n);//因為code對象數組是來回使用的,因此只能創建一個新的,把指定的位置傳入到新的for(int?j=code.start+1;j?<?n;j++){temp.bit[j]?=?code.bit[j];}temp.weight?=?code.weight;temp.start?=?code.start;haffCode[i]?=?temp;} } }

測試類

public?class?Test?{public?static?void?main(String[]?args)?{int?n?=?4;int[]?weight?=?{1,3,5,7};HaffmanTree?haffTree?=?new?HaffmanTree(n);HaffNode[]?nodes?=?new?HaffNode[2*n-1];Code[]?codes?=?new?Code[n];?//構造哈夫曼樹haffTree.haffman(weight,?nodes);//生成哈夫曼編碼haffTree.haffmanCode(nodes,?codes);//打印哈夫曼編碼for(int?i=0;i<n;i++){System.out.print("Weight="+codes[i].weight+"?Code=");//編碼打印時,長度都一樣,只是開始的位置不同,由編碼類封裝了for(int?j=codes[i].start+1;j<n;j++){System.out.print(codes[i].bit[j]); }System.out.println();}}}


轉載于:https://blog.51cto.com/wukong0716/1692140

總結

以上是生活随笔為你收集整理的学习日志---哈夫曼树相关算法的全部內容,希望文章能夠幫你解決所遇到的問題。

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