`
zhouYunan2010
  • 浏览: 207534 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类

最优二叉树(哈弗曼树)

阅读更多
   提到哈弗曼树就必须提到节点权值,权值一般具有实际意义,比如此节点出现的概率,次数等。
必须提供权值才能构建出一棵哈弗曼树,因为哈弗曼树的定义为带权路径长度最小的二叉树。
树的带权路径长度为所有叶子节点的带权路径长度。
节点的带权路径长度为该节点到树的路径长度乘以节点权值。
哈希曼树最主要的应用是产生哈希曼编码。
为特点元素设计哈希曼编码要求二进制编码尽可能的短,并且任意一个字符的编码不是另外一个
字符的编码的前缀。


下面通过java代码构建哈希曼树与设计哈希曼编码
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);
		}
	}
		
}


分享到:
评论

相关推荐

    哈夫曼(最优二叉树)C语言版

    哈夫曼编码是一种数据压缩方法,它利用了字符出现频率的不同来构建一棵特殊的二叉树——哈夫曼树。在哈夫曼树中,频率较高的字符对应的路径较短,而频率较低的字符路径较长,这样可以使得频繁出现的字符在编码时使用...

    完全二叉树,哈弗曼树应用觉对经典

    接下来,我们讨论哈弗曼树,也称为最优二叉树。哈弗曼树是一种带权路径长度最短的二叉树,用于数据的编码和解码,特别是在数据压缩中扮演着重要角色。构建哈弗曼树的过程通常通过哈弗曼编码来实现,这是一种贪心算法...

    哈弗曼树的建立 C++代码

    哈弗曼树,又称最优二叉树,是一种带权路径长度最短的二叉树,在数据压缩、编码等领域有广泛应用。哈弗曼树的构建基于贪心算法思想,其核心目标是使树的带权路径长度最小。树中的每个叶子节点代表一个字符,而其权重...

    数据结构课程设计 包括 链表 共享栈 队列 二叉树与哈弗曼树

    - **最优二叉树(哈弗曼树)**:一种带权路径长度最短的二叉树,用于数据编码,例如文件压缩。 6. **哈弗曼树**: - **构建过程**:通过哈弗曼编码算法,根据各节点的权重构建最小带权路径长度的二叉树。 - **...

    哈弗曼树的生成(编码)

    总的来说,哈弗曼树的生成和编码是一种有效的数据压缩方法,它利用了数据的统计特性,通过构造最优的二叉树结构,使得高频字符的编码更短,从而提高压缩效率。在实际应用中,如在文件压缩软件中,哈弗曼编码常常与...

    关于哈弗曼树的一个算法

    哈弗曼树,又称最优二叉树,是一种带权路径长度最短的二叉树,由美国计算机科学家哈弗曼在1952年提出,主要用于数据编码,特别是在数据压缩领域有着广泛的应用。哈弗曼树通过构建一个特殊的二叉树结构,可以使得树中...

    哈弗曼树进行压缩编码

    哈弗曼树(Huffman Tree),也称为最优二叉树,是一种特殊的二叉树结构,广泛应用于数据压缩领域。在信息编码中,哈弗曼编码是一种可变长度的前缀编码方式,它根据字符出现频率构建哈弗曼树,使得出现频率高的字符...

    哈弗曼树C++源代码

    哈弗曼树(Huffman Tree),也称为最优二叉树,是一种特殊的二叉树,用于数据编码和解码,尤其在数据压缩领域有着广泛应用。它是由哈弗曼在1952年提出的一种构建方法,旨在最小化带权路径长度(WPL),即树中所有...

    C++哈弗曼树

    在IT领域,哈弗曼树(Huffman Tree)是一种特殊的二叉树,也称为最优二叉树或最小带权路径长度树(Minimum Weighted Path Length Tree)。它在数据压缩、编码优化等方面有广泛应用,比如在文件存储和传输时,通过...

    哈弗曼树的建立及哈弗曼编码的生成 c++实现

    哈弗曼树(Huffman Tree),也称为最优二叉树,是数据结构中的一种特殊二叉树,主要用于数据的编码和解码,特别是在文本压缩中起到关键作用。它通过一种贪心策略构建,使得带权路径长度最短,从而达到编码效率最高。...

    C++哈弗曼树!哈弗曼树

    哈弗曼树,又称最优二叉树或最小带权路径长度树,是数据结构领域中的一个重要概念,尤其在数据编码和压缩中有着广泛的应用。它是一种特殊的二叉树,其特性是任何节点的两个子节点都是空节点或者权值较小的节点在左,...

    数据结构哈弗曼树课程设计

    哈弗曼树,也称为最优二叉树,是通过哈弗曼编码实现数据压缩的关键工具。 哈弗曼树是一种特殊的二叉树,其特点是所有叶子节点(通常代表字符或数据元素)都在最底层,且没有左孩子节点的节点比有左孩子节点的节点离...

    数据结构之哈弗曼树实现压缩

    哈弗曼树(Huffman Tree),也称为最优二叉树,是数据结构中的一种特殊树形结构,主要用于数据编码和解码,特别是用于数据压缩。它通过构建一棵权值最小的二叉树来达到最高效的编码效果。在哈弗曼树中,频率较高的...

    用C语言实现哈弗曼树(数据结构课程设计)

    哈弗曼树,又称最优二叉树或最小带权路径长度树,是一种特殊的二叉树,广泛应用于数据压缩、文件编码等领域。在数据结构课程设计中,使用C语言实现哈弗曼树是一个经典且富有挑战性的任务。下面将详细介绍如何用C语言...

    哈弗曼树编码(c语言+数据结构)

    1. **哈弗曼树**:也称为最优二叉树,是一种带权路径长度最短的二叉树。树中的每个叶子节点代表一个待编码的字符,权值即为字符的频率;非叶子节点则由两个子节点合并而成,权值为其子节点权值之和。 2. **哈弗曼...

    指针实现哈弗曼树

    哈弗曼树(Huffman Tree),也称为最优二叉树,是一种特殊的二叉树结构,广泛应用于数据压缩中。在哈弗曼树中,每个叶子节点代表一个需要编码的字符,而权重通常表示该字符在文本中的出现频率。构建哈弗曼树的过程是...

    哈弗曼树与编码解码

    哈弗曼树(Huffman Tree),也称为最优二叉树,是数据压缩中的一种关键算法。它是基于贪心策略构建的,主要用于实现哈弗曼编码(Huffman Coding),这是一种无损数据压缩方法。哈弗曼编码通过为每个字符分配一个唯一...

    c++哈弗曼树的解码与编码

    哈弗曼编码是一种高效的数据压缩方法,它利用了字符出现频率的不同来构建最优的二叉树,即哈弗曼树。在哈弗曼编码中,出现频率高的字符对应的编码长度较短,反之则较长,从而使得频繁出现的字符在编码过程中占用较少...

    哈弗曼树编码课程设计

    哈弗曼树,又称为最优二叉树或最小带权路径长度树,是根据字符出现频率构建的一种特殊的二叉树。它的特点是:树中任一节点的两个子树的高度差不超过1;所有叶子节点(代表字符)都位于最底层,且左子树代表的字符...

Global site tag (gtag.js) - Google Analytics