zoukankan      html  css  js  c++  java
  • 哈夫曼树的介绍 ---java实现

    一、     什么是哈夫曼树

    是一种带权路径长度最短的二叉树,也称最优二叉树

    带权路径长度:WPL=(W1*L1+W2*L2+W3*L3+...+ Wn*Ln)

    N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树。对应的叶结点的路径长度为Li(i=1,2,...n)

    二、     建立哈夫曼树

    已知的一组叶子的权值w1,w2,w3……wn; 
    首先把 个叶子结点看做 棵树(仅有一个结点的二叉树)。把它们看做一个森林。

     
    在森林中把权值最小和次小的两棵树合并成一棵树。该树根结点的权值是两棵子树权值之和。

    这时森林中还有 n-1 棵树。

     
    反复第步直到森林中仅仅有一棵为止。此树就是哈夫曼树。

    现给一组 (n=4) 详细的权值: 2    ,下边是构造详细过程:

     

    n 个叶子构成的哈夫曼树其带权路径长度是唯一的。但树形是不唯一的。由于将森林中两棵权值最小和次小的子棵合并时,哪棵做左子树,哪棵做右子树并不严格限制。

     

    三、     哈夫曼树的应用


    a)       哈夫曼编码

     利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每一个叶子节点都有一条路径,对路径上的各分支约定指向左子树的分支表示”0”码,指向右子树的分支表示“1”码。取每条路径上的“0”或“1”的序列作为各个叶子节点相应的字符编码,即是哈夫曼编码。

    当中A,B,C,D相应的哈夫曼编码分别为:111。10,110。0


    b)      二路归并排序

    如果如今有n个已经排序的文件{d1,d2,….dn}。每一个文件包括的记录个数相应是{w1,w2,w3…..wn};能够採用两两合并的方法,把所有文件的记录合并到一个大文件里,使得这个文件里的记录所有排序。

                  问:採用什么合并次序才干使移动个数最少?

                  答:依照哈夫曼树的结构从外部结点到根节点逐层进行合并,一定是一种最佳的合并顺序。

     



    四、      哈夫曼树的代码实现

    用java实现的哈夫曼树
    public class Huffman {
    	public static void main(String[] args){
    		Huffman huffman = new Huffman();
    		int[] a = {2,3,5,7,11,13,17,19,23,29,31,37,41};
    		System.out.println(a.length);
    		HfTree tree = huffman.createHfTree(a.length , a);
    		System.out.println("ht  ww  parent  lchild  rchild ");
    		for(int i=0;i<tree.node.length;i++){
    			System.out.println(i +" "+ tree.node[i].ww +" "+ tree.node[i].parent +" "+ tree.node[i].lchild +" "+ tree.node[i].rchild);
    		}
    		
    	}
    	
    	private static int MAXINT=10000;
    	public HfTree createHfTree(int m , int a[]){
    		HfTree hfTree = new HfTree(m);
    		/*初始化哈夫曼树*/
    		for(int i=0;i<2*m-1;i++){
    			hfTree.node[i].lchild = -1;
    			hfTree.node[i].rchild = -1;
    			hfTree.node[i].parent = -1;
    			if(i<m){
    				hfTree.node[i].ww = a[i];
    			}
    		}
    		/*開始生成哈夫曼树*/
    		for(int i=0; i<m-1;i++){
    			int x1 = 0;
    			int x2 = 0;
    			int m1 = MAXINT;
    			int m2 = MAXINT;
    			for(int j=0; j<m+i;j++){
    				if(hfTree.node[j].ww < m1 && hfTree.node[j].parent == -1){
    					m2 = m1;
    					x2 = x1;
    					m1 = hfTree.node[j].ww;
    					x1 = j;
    				}
    				else if(hfTree.node[j].ww < m2 && hfTree.node[j].parent == -1){
    					m2 = hfTree.node[j].ww;
    					x2 = j;
    				}
    			}
    			hfTree.node[x1].parent = m+i;
    			hfTree.node[x2].parent = m+i;
    			hfTree.node[m+i].ww = m1+m2;
    			hfTree.node[m+i].lchild = x1;
    			hfTree.node[m+i].rchild = x2;
    		}
    		hfTree.root = 2*m-2;
    		return hfTree;
    	}
    	
    	
    	
    }
    
    
    class HfNode{
    	public int ww;
    	public int parent;
    	public int lchild;
    	public int rchild;
    	
    }
     
    class HfTree{
    	  public HfNode[] node;
    	  public int root;
    	  public int m;
    	 
    	 HfTree(int m){
    		 this.m = m;
    		 this.node = new HfNode[2*m-1];
    		//初始化对象数组是必须每一个对象都创建
    		 for(int i=0;i<2*m-1;i++){
    			 node[i] = new HfNode(); 
    		 }
    	 }
    	
    
    		
     }
     
    


  • 相关阅读:
    flock对文件锁定读写操作的问题 简单
    hdu 2899 Strange Fuction(二分)
    hdu 2199 Can you solve this equation? (二分)
    poj 3080 Blue Jeans (KMP)
    poj 2823 Sliding Window (单调队列)
    poj 2001 Shortest Prefixes (trie)
    poj 2503 Babelfish (trie)
    poj 1936 All in All
    hdu 3507 Print Article (DP, Monotone Queue)
    fzu 1894 志愿者选拔 (单调队列)
  • 原文地址:https://www.cnblogs.com/llguanli/p/8321653.html
Copyright © 2011-2022 走看看