序文:
ハフマンツリーは最小スパンツリーです。
構築プロセスは次のとおりです。
ハフマンツリーは一意ではありませんが、加重パスの長さは同じである必要があります。
次のように、重みが1、5、8、4の4つのノード
ハフマンツリーの構築プロセスは次のとおりです。
一般に、次の手順に要約できます。
n個の重みがあると仮定すると、構築されたハフマンツリーにはn個のリーフノードがあります。n個の重みはそれぞれw1、w2、...、wnとして設定され、ハフマンツリーの構築ルールは次のとおりです。
1. w1、w2、...、wnをn本のツリーを持つフォレストと見なします(各ツリーにはノードが1つだけあります)
。2。フォレストで、マージするルートノードの重みが最小の2つのツリーを選択します。 、新しいツリーの左右のサブツリーとして、新しいツリーのルートノードの重みは、その左右のサブツリーのルートノードの重みの合計です。3。
選択した2つのツリーをフォレストから削除し、フォレストに新しいツリーを追加します
。4。取得したハフマンツリーであるツリーがフォレストに1つだけ残るまで、手順(02)と(03)を繰り返します。
言うまでもありませんが、コードは次のとおりです。
package Huffman树;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Huffman {
static class node implements Comparable<node>{//自排序
int weight;//权值
node lchild;
node rchild;
public node(int w,node l,node r)
{
this.weight=w;
this.lchild=l;
this.rchild=r;
}
public int compareTo(node o) {
return this.weight-o.weight;
}
}
static node createHuffmanTree(ArrayList<node> nodes)
{
while(nodes.size()>1)
{
Collections.sort(nodes);//排序
node l=nodes.get(0);
node r=nodes.get(1);
//System.out.println(l.weight+" "+r.weight);
node p=new node(l.weight+r.weight,l,r);
//移走两个最小的
nodes.remove(0);
nodes.remove(0);
//把大的放进去
nodes.add(p);
}
return nodes.get(0);
}
//前序遍历,并求WPL 带权路径长度
static long WPL=0;
static void preorder(node root,int levelNum)
{
if(root.lchild==null)
{
WPL+=root.weight*levelNum;
return;
}
else
{
preorder(root.lchild,levelNum+1);
preorder(root.rchild,levelNum+1);
}
}
public static void main(String[] args) {
ArrayList<node> nodes=new ArrayList<node>();
Scanner cin=new Scanner(System.in);
int n=cin.nextInt();
for(int i=0;i<n;i++)
{
int w=cin.nextInt();//这里我直接把它的权值当做name了
nodes.add(new node(w,null,null));
}
node r=createHuffmanTree(nodes);
WPL=0;//WPL:带权路径长度
preorder(r,0);
System.out.println("WPL: "+WPL);
cin.close();
}
}