• 哈夫曼树的介绍 ---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(); 
    		 }
    	 }
    	
    
    		
     }
     
    


  • 相关阅读:
    06-python基础-基本数据类型介绍
    05 python开发的IDE之一--pycharm以及基本的运算符
    04 python基础-变量及如果语句的作业
    03 python基础-变量
    02 python的安装及分类
    es6的标签整体引用及引入变量
    django之auth组件【知识点补充】
    BootStrap让两个控件在一行显示(label和input同行)
    django 将view视图中的对象传入forms表单验证模块中
    Django ajax异步请求分页的实现
  • 原文地址:https://www.cnblogs.com/llguanli/p/8321653.html
Copyright © 2020-2023  润新知