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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

哈弗曼树的实现

發布時間:2025/4/16 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哈弗曼树的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?提到哈弗曼樹就必須提到節點權值,權值一般具有實際意義,比如此節點出現的概率,次數等。?
必須提供權值才能構建出一棵哈弗曼樹,因為哈弗曼樹的定義為帶權路徑長度最小的二叉樹。?
樹的帶權路徑長度為所有葉子節點的帶權路徑長度。?
節點的帶權路徑長度為該節點到樹的路徑長度乘以節點權值。?
哈希曼樹最主要的應用是產生哈希曼編碼。?
為特點元素設計哈希曼編碼要求二進制編碼盡可能的短,并且任意一個字符的編碼不是另外一個?

字符的編碼的前綴。

package com.algorithm;


/**
?* 最優二叉樹(哈夫曼樹)
?* 根據元素的權值構建哈夫曼樹,并設計其哈弗曼編碼
?* 使用數組存儲節點
?*/
public class Hufuman {
private int[] weights; //存儲權值
private int n;
private TreeNode[] nodes; //存儲節點的數組
private int m; //數組長度


class TreeNode{
int weight; //權值
int Parent; //父節點的下標
int lchild; //左孩子下標
int rchild; //右孩子下標

public TreeNode(int weight,int parent,int lchild,int rchild){
this.weight = weight;
this.Parent = parent;
this.lchild = lchild;
this.rchild = rchild;
}
}

public Hufuman(){

}

public Hufuman(int[] w){
this.weights = w;
int n = w.length;
if(n <= 1){
throw new IllegalArgumentException();
}
this.n = n;
init();
}

/**
* 初始化節點數組
*/
private void init(){
? ?m = 2*n - 1;
nodes = new TreeNode[m];
int i;
for(i = 0;i < n ;++i){
nodes[i] = new TreeNode(weights[i], -1, -1, -1); //-1表示無父或孩子節點
}
for(;i < m;++i){
nodes[i] = new TreeNode(-1, -1, -1, -1);
}
}

/**
* 根據權值構建哈夫曼樹
*/
public void create(){
int min,secmin;
for(int i = n;i < m;++i){
int[] mins = select(i-1);
min = mins[0];
secmin = mins[1];
nodes[min].Parent = i ;
nodes[secmin].Parent = i;
nodes[i].lchild = min;
nodes[i].rchild = secmin;
nodes[i].weight = nodes[min].weight + nodes[secmin].weight;


}
}

/**
* 從葉子節點逆向求每個字符的哈弗曼編碼
*/
public String[] hufumanCoding(){
String[] codes = new String[n];
StringBuilder sb ;
for(int i=0;i<n;++i){ //i到n都是葉子節點
sb = new StringBuilder();
for(int c=i,p=nodes[i].Parent;p!=-1;c=p,p=nodes[p].Parent){
if(nodes[p].lchild == c)
sb.append('0'); //左分支表示字符'0'
else
sb.append('1'); //右分支表示字符'1'
}
codes[i] = sb.reverse().toString();
}
return codes;
}

/**
* 取weight最小的兩個節點
*/
private int[] select(int last){
int min=0; //最小值下標
int secmin=0; //次小值下標
int i;
for(i=0;i<=last;++i){
if(nodes[i].Parent==-1){
min = i;
break;
}
}
for(i=i+1;i<=last;++i){
if(nodes[i].Parent==-1){
secmin = i;
break;
}
}
int temp;
if(nodes[min].weight > nodes[secmin].weight){
temp = min;
min = secmin;
secmin = temp;
}
for(i=i+1;i<=last;++i){
if(nodes[i].Parent!=-1)continue;
if(nodes[i].weight < nodes[min].weight){
secmin = min;
min = i;
}else{
if(nodes[i].weight < nodes[secmin].weight)
secmin = i;
}
}
int[] minValues = {min,secmin};
return minValues;
}

public void printTree(){
System.out.println(" ? | weight | parent | lchild | rchild |");
for(int i=0;i<m;i++){
System.out.print(i+" ?| ? "+nodes[i].weight+" ? | ? "+nodes[i].Parent+" ? | ? "+nodes[i].lchild+" ? | ? "+nodes[i].rchild+" ? |");
System.out.println();
}
}

public static void main(String[] args) {
int[] w = {5,29,7,8,14,23,3,11};
Hufuman t = new Hufuman(w);
t.create();
t.printTree();
String[] str = t.hufumanCoding();
for(String s:str){
System.out.println(s);
}
}

}

轉自:http://zhouyunan2010.iteye.com/blog/1184303

總結

以上是生活随笔為你收集整理的哈弗曼树的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

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