Huffman树的原理以及代码构建_如何构造huffman树-程序员宅基地

技术标签: 算法  Java基础学习系列  数据结构  

我们的目标认识只是基础,代码实现是才是核心

1.Huffman树的定义:

        从树中一个结点到另一个结点的之间的分支构成两个结点之间的路径,路径上的分支数称为路径长度。那么树的路径长度就是从树根到每一个结点的路径之和。带权路径长度WPL最小的二叉树叫做Huffman树。

二叉树的WPL = 5 * 3 + 15 * 3 + 40 * 2 + 30 * 2 + 10 * 2 = 220

2.Huffman树的构建

        这还不是一棵Huffman树,我们需要以下几个步骤

1.先把有权值的叶子结点按照从小到大的顺序排列成一个有序序列:A5,E10,B15,D30,E40.

2.取头两个最小权值的结点作为一个新节点N1的两个子节点,注意我们通常以相对较小的是左孩子,这里A就是N1的左孩子,E为N1的右孩子。新节点的权值为;两个叶子的权值和 5 + 10 = 10.

                                                                                                         

 3.将N1替换成A与E,插入有序序列中,保持从小到大排列。即:N1(15),B15, D30,C40

 4.重复2的操作,将N1和B作为一个新节点N2的两个子节点。


5.将N2替换N,与B,插入有序序列中,保持从小到大排列。即: N230, D30C40。

6.重复步骤2。将N2与D作为一个新节点N3的两个子结点。N3的权值=30+30=60。



7.将N3替换N2与D,插入有序序列中,保持从小到大排列。即: C40, N360。

8.重复步骤2。将C与Ngs作为1个新节点T的两个子结点。由于T即是根结点,完成赫夫曼树的构造。

此时带权路径长度 WPL = 40 * 1 + 30 * 2 + 15 * 3 + 10 * 4 +5 * 4 = 205 < 220 huffman树。

Huffman编码只需要把左孩子权值写成0,右孩子写成1,然后从根节点到叶子经过的路径就是它的编码。

 A:1000        B:101        C:0        D:11        E:1001

3.代码实现


package datastructure.tree;

import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;

public class Huffman {

	/** 用来存放节点值 */
	private static LinkedList<HuffNode> huffList = new LinkedList<HuffNode>();
	
	public static void main(String[] args) {
		//输入数据
		System.out.println("先输入数据个数回车,在输入数据");
		System.out.println("请输入: ");
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		for (int i = 0; i < n; i++) {
			//数据输入控制循环
			huffList.add(new Huffman().new HuffNode(sc.next(),sc.nextInt() ));
		}
		huffmanCode();
		decode(huffList.get(0), "");
	}
	
	class HuffNode implements Comparable<HuffNode> {
		/** 权值 */
		int value;
		String name;
		/** 左孩子节点 */
		HuffNode lChild = null;
		/** 右孩子节点 */
		HuffNode rChild = null;
		/*
		 * 构造方法,用于输入初始化Huffman结点
		 */
		public HuffNode(String name, int value) {
			this.value = value;
			this.name = name;
		}
		//构建Huffman树时的构造方法
		public HuffNode(HuffNode lChild, HuffNode rChild) {
			this.lChild = lChild;
			this.rChild = rChild;
			// 权值之和,即合并两个叶子节点
			this.value = lChild.value + rChild.value;
		}
		/**********************
		* @param next
		* @param nextInt
		*********************
		*/
		/**
		 * 重新写比较方法
		 */
	    public int compareTo(HuffNode o) {
	    	if (this.value < o.value) {
	    		return -1;
	    	} else if (this.value == o.value) {
	    		return 0;
	    	} else {
	    		return 1;
	    	}
	    }
	}
	
	//Huffman树构建和编码
	public static void huffmanCode() {
		/*
		 * 当所剩结点为一时构造Huffman树成功
		 * 否则执行循环直到Huffman树的结点为一结束
		 */
		if (huffList.size() == 1) {
			return ;
		}
		while (huffList.size() > 1) {
			// 排序
			Collections.sort(huffList);
			// 将前两个节点进行合并
			HuffNode node = new Huffman().new HuffNode(huffList.get(0), huffList.get(1));
			// 删除前两个节点
			huffList.remove();
			huffList.remove();
			// 将新生成的节点添加到列表中
			huffList.add(node);
		}
		// 编码完成后,此时huffList中只剩一个根节点
	}
	
	//解码方法,我们的编码是叶子结点,所以当左右孩子为空时就输出
	public static void decode(HuffNode n, String code) {
		if ((n.lChild == null) && (n.rChild == null)) {
			// 叶子节点, 此时输出其对应编码
			System.out.print(n.name + "--->" + code);
			System.out.println();
			return ;
		}
		// 遍历左子树
		decode(n.lChild, code + "0");
		// 遍历右子树
		decode(n.rChild, code + "1");
		return ;
	}
}

 测试数据:

5
A 5
B 15
C 40
D 30
E 10

运行结果:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_51294669/article/details/122483039

智能推荐

美团图数据库平台建设及业务实践_美团点评 海量图片分布式图片存储的 底层技术-程序员宅基地

文章浏览阅读6.1k次,点赞6次,收藏16次。总第442篇2021年 第012篇图数据结构,能够更好地表征现实世界。美团业务相对较复杂,存在比较多的图数据存储及多跳查询需求,亟需一种组件来对千亿量级图数据进行管理,海量图数据的高效存储..._美团点评 海量图片分布式图片存储的 底层技术

ElasticSearch入门_opensearch wildcard-程序员宅基地

文章浏览阅读1.7k次。第一节 ElasticSearch概述1.1 ES 分布式的全文搜索引擎。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulweb接口。ElasticSearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。构建在全文检索开源软件Lucene之上的Elasticsear..._opensearch wildcard

(防坑笔记)hadoop3.0 (一) 环境部署与伪分布式(hdfs)-程序员宅基地

文章浏览阅读1.3w次,点赞21次,收藏42次。防坑留名:为了避免以后自己遇到什么坑爹的东西,先留脚印给自己。这个hadoop呢,主要是可以让用户可以在不了解分布式底层细节的情况下,开发分布式程序,充分利用集群的威力进行高速运算和存储。这点比较厉害了。它主要是用来做数据分析,支持低端服务器集群(这点美滋滋- - ),先抓取大量数据,利用数据运算分析,获取日志,显示报表~~~~~;_hadoop3.0

编写求立方根函数double cube(double x);函数返回参数的立方根。中国海洋大学03-04年第二学期《C程序设计期中考试》第三题编程题的第三题_double cube(double x);-程序员宅基地

文章浏览阅读801次。题目本题是中国海洋大学03-04年第二学期《C程序设计期中考试》第三题编程题的第三题。题目:编写求立方根函数double cube(double x);函数返回参数的立方根。主函数如下:。main() { double cube(double x); double x; scanf("%lf", &x); printf("cube(%lf)=%lf\n", cube(x));}以下是本篇文章正文内容,欢迎朋友们进行指正,一起探讨,共同进步。——来自考研路上的lwj一、解题_double cube(double x);

和oscp相似的靶机-hackthebox & vulnhub (OSCP-LIKE HACKTHEBOX & VULNHUB)_lnhub hackthebox vulnstack vulntarget-程序员宅基地

文章浏览阅读2.9k次,点赞2次,收藏14次。每台都做一做,然后记录在博客里.供自己和大家一起学习._lnhub hackthebox vulnstack vulntarget

Debian 6 安装小记_linux pardus 6.1.0-17-amd64 #1 smp preempt_dynamic-程序员宅基地

文章浏览阅读1.1k次。Debian 6 安装小记07.31.2011 · Posted in LAMP上个月入手了mac,就把thinkpadr400冷落了蛮久。想着太浪费了,于是想着开始折腾系统。最开始是考虑unix中的freebsd, openbsd, netbsd,后来觉得还是回_linux pardus 6.1.0-17-amd64 #1 smp preempt_dynamic debian 6.1.69-1 (2023-12-

随便推点

常见缓存架构原理_缓存框架的原理-程序员宅基地

文章浏览阅读1.2k次,点赞4次,收藏2次。互联网公司在缓存架构上是区分很大的,往往是根据企业的业务量来进行选择的,可以看如下图在传统的小型互联网公司,采用网页静态化技术,freemarker来加快用户的体验速度,从来来提升响应,但是如果出现了缓存血崩,缓存击穿那么对数据库将会造成很大的压力,可能导致整个架构无法使用一 缓存击穿  缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写..._缓存框架的原理

宏定义中的可变参数 __VA_ARGS__ 用法 与 #和##的用法_##__va_args__-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏3次。首先了解一下可变参数#include <stdio.h> #define DEBUG(fmt, ...) printf(fmt, __VA_ARGS__)int main(){ DEBUG("you know i am handsome%d,%f,%d", 1000, 1.1, 10); return 0;}输出:you know i am handsome1000,1.100000,10这里的__VA_ARGS__其实就是指代…三个省略号的内容了,这_##__va_args__

高德地图+echarts实现飞线图_import echartsamap from "echarts-amap";-程序员宅基地

文章浏览阅读9.3k次。下面是vue实现,原生html后续贴上来前期准备:引入amap、echarts、echarts-amap依赖,vue的话需要npm安装一下By using script tag<!--引入高德地图JSAPI --> <script src="//webapi.amap.com/maps?v=1.4.15&key=ab99f68b8f9eac7a5287f..._import echartsamap from "echarts-amap";

Flowable 6.6.0表单 - 1.配置 - 1.2 FormEngineConfiguration bean_form engine is not initialized-程序员宅基地

文章浏览阅读574次。The flowable.form.cfg.xml must contain a bean that has the id ‘formEngineConfiguration’.这个flowable.form.cfg.xml必须包含id为“formEngineConfiguration”的bean。 <bean id="formEngineConfiguration" class="org.flowable.form.engine.impl.cfg.StandaloneFormEngineConfi_form engine is not initialized

yocto依赖关系小结_yocto depends-程序员宅基地

文章浏览阅读4.6k次,点赞2次,收藏12次。首先说明,yocto中的依赖本质上是任务之间的依赖,即使是使用DEPENDS或者RDEPENDS定义的两个recipe之间的依赖关系,但实际上在yocto运行时依赖关系还是会体现在这两个recipe中的task之间,即在运行时,yocto会将recipe之间的依赖解析成task之间的依赖。task之间的依赖关系可以分为两种:属于同一个recipe的task之间的依赖或者属于不同recipe的ta..._yocto depends

亿级Web系统搭建:单机到分布式集群-程序员宅基地

文章浏览阅读162次。当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题。为了解决这些性能压力带来问题,我们需要在Web系统架构层面搭建多个层次的缓存机制。在不同的压力阶段,我们会遇到不同的问题,通过搭建不同的服务和架构来解决。Web负载均衡Web负载均衡(Load Balan

推荐文章

热门文章

相关标签