【数据结构(十·树结构的实际应用)】赫夫曼树(2)

文章目录

  • 1. 基本介绍
  • 2. 赫夫曼树的创建
    • 2.1. 思路分析
    • 2.2. 代码实现


1. 基本介绍

  1. 给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,若该树的 带权路径长度(wpl) 达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍(赫)夫曼树
  2. 赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

几个重要的概念:
    ① 路径路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为 1,则从根结点到第 L 层结点的路径长度为 L-1。
    ② 结点的权带权路径长度:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。
    ③ 树的带权路径长度:树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为 WPL(weighted path length) ,权值越大的结点离根结点越近的二叉树才是最优二叉树。

WPL 最小的就是赫夫曼树
    在这里插入图片描述

2. 赫夫曼树的创建

问题:
    给一个数列 {13, 7, 8, 3, 29, 6, 1},要求转成一颗赫夫曼树.

2.1. 思路分析

    ① 从小到大进行排序, 将每一个数据,每个数据都是一个节点 , 每个节点可以看成是一颗最简单的二叉树
    ② 取出根节点权值最小的两颗二叉树
    ③ 组成一颗新的二叉树, 该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和
    ④ 再将这颗新的二叉树,以根节点的权值大小 再次排序, 不断重复 1-2-3-4 的步骤,直到数列中,所有的数据都被处理,就得到一颗赫夫曼树

图解:

① 从小到大进行排序{1, 3, 6, 7, 8, 13, 29}, 将每一个数据,每个数据都是一个节点 , 每个节点可以看成是一颗最简单的二叉树
在这里插入图片描述

② 取出根节点权值最小的两颗二叉树,即1和3
在这里插入图片描述

③ 组成一颗新的二叉树, 该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和(1+3=4)

在这里插入图片描述

④ 再将上面这颗新的二叉树,以根节点的权值大小 再次排序:取出上面 以根节点为4和6的二叉树,重复③步骤

在这里插入图片描述

⑤ 不断重复上述操作,直到数列中,所有的数据都被处理,就得到一颗赫夫曼树
    (1)重复第一次

在这里插入图片描述

    (2)重复第二次

在这里插入图片描述

    (3)重复第三次

在这里插入图片描述

    (4)重复第四次(完成)

在这里插入图片描述

2.2. 代码实现

package huffmantree;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class HuffmanTree {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int arr[] = { 13, 7, 8, 3, 29, 6, 1 };

		Node root = createHuffmanTree(arr);

		// 测试
		preOrder(root);//

	}

	// 编写一个前序遍历的方法
	public static void preOrder(Node root) {
		if (root != null) {
			root.preOrder();
		} else {
			System.out.println("是空树,不能遍历~");
		}
	}

	// 创建赫夫曼树方法
	/**
	 * 
	 * @param arr 需要创建成赫夫曼树的数组
	 * @return 创建好后的赫夫曼树的root节点
	 */
	public static Node createHuffmanTree(int[] arr) {
		// 第一步:为了操作方便
		// 1. 遍历arr数组
		// 2. 将arr的每个元素构成一个Node
		// 3. 将Node放入到ArrayList中
		List<Node> nodes = new ArrayList<>();
		for (int value : arr) {
			nodes.add(new Node(value));
		}

		// 处理的过程是一个循环的过程
		while (nodes.size() > 1) {

			// 排序:从小到大
			Collections.sort(nodes);
			System.out.println("nodes = " + nodes);

			// 取出根节点权值最小的两个二叉树
			// 1. 取出权值最小的节点(二叉树)
			Node leftNode = nodes.get(0);
			// 2. 取出第二小的节点(二叉树)
			Node rightNode = nodes.get(1);

			// 3. 构建一个新的二叉树
			Node parent = new Node(leftNode.value + rightNode.value);
			parent.left = leftNode;
			parent.right = rightNode;

			// 4. 从ArrayList删除处理过的二叉树
			nodes.remove(leftNode);
			nodes.remove(rightNode);

			// 5. 将parent加入到nodes
			nodes.add(parent);
		}

		// 返回赫夫曼树的root节点
		return nodes.get(0);

	}

}

//创建节点类
//为了让Node对象持续排序Collections集合排序
//让Node实现Comparable接口
class Node implements Comparable<Node> {
	int value;// 节点权值
	Node left;// 指向左节点
	Node right;// 指向右节点

	// 写一个前序遍历
	public void preOrder() {
		System.out.println(this);
		if (this.left != null) {
			this.left.preOrder();
		}
		if (this.right != null) {
			this.right.preOrder();
		}
	}

	public Node(int value) {
		this.value = value;
	}

	@Override
	public String toString() {
		return "Node [value=" + value + "]";
	}

	@Override
	public int compareTo(Node o) {
		// TODO Auto-generated method stub
		// 表示从小到大排序
		return this.value - o.value;
	}

}

运行结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/235107.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FL Studio21最新FL水果编曲软件中文版在哪下载?

FL Studio21水果编曲软件是一款专业的音乐制作软件&#xff0c;被广泛地应用于电子音乐、hip-hop、流行乐等多种音乐类型的制作。该软件提供了丰富的音频编曲工具和音乐效果器&#xff0c;让用户可以轻松地创作出高品质的音乐作品。同时&#xff0c;这也是一款非常易于上手的软…

登录rabbitMQ管理界面时浏览器显示要求进行身份验证,与此站点连接不安全解决办法

问题描述 最近在黑马学习rabbitMQ的过程中&#xff0c;在使用docker部署好rabbitMQ后&#xff0c;使用账号为&#xff1a;itcast&#xff0c;密码为&#xff1a;123321 登录的时候浏览器显示了这个问题&#xff0c;如图所示&#xff1a; 当时以为自己需要输入自己的浏览…

【Apipost】批量删除我的51CTO文章

文章目录 一、序二、API分析三、Apipost测试四、脚本五、Apipost中完成 一、序 去年开始再51CTO同步更新文章&#xff0c;一年多过去了&#xff0c;只涨了3个粉丝。看了下这个平台就是卖课、搞培训的&#xff0c;退出了。决定把文章也删除了&#xff08;有人私信我说专门注册了…

RCNN 学习

RCNN算法流程 RCNN算法流程可分为4个步骤 一张图像生成1K~2K个候选区域&#xff08;使用Selective Search方法&#xff09;对每个候选区域&#xff0c;使用深度网络图特征特征送入每一类的SVM分类器&#xff0c;判别是否属于该类使用回归期器细修正候选框位置 1.候选区域的生…

【论文极速读】视频检索中的模态均衡方法

【论文极速读】视频检索中的模态均衡方法 FesianXu 20231206 at Baidu Search Team 前言 传统的视频搜索系统相关性部分主要以文本匹配为基础手段&#xff0c;在其中引入多模态向量容易收到『模态不均衡』的问题&#xff0c;论文[1]尝试对其进行解决&#xff0c;本文进行笔记。…

二维码智慧门牌管理系统升级解决方案:数字化房产管理

文章目录 前言一、全面信息记录&#xff1a;提升管理效率二、多种优势功能&#xff1a;系统化管理与无缝对接三、安全隐私保护&#xff1a;数据安全的重要性四、总结&#xff1a;提升管理效率与居住体验 前言 科技驱动房产管理 随着科技的飞速发展&#xff0c;房产管理领域也面…

udp多播组播

import socket ,struct,time# 组播地址和端口号 MCAST_GRP 239.0.0.1 MCAST_PORT 8888 # 创建UDP socket对象 sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # 绑定socket对象到本地端口号 # sock.bind((MCAST_GRP, MCAST_PORT)) …

D28|买卖股票的最佳时机+跳跃游戏

122.买卖股票的最佳时机 II 初始思路&#xff1a; 这道题解题的时候比较像在找规律&#xff0c;发现只要计算这个过程中的两数之差然后相加即可。 题解复盘&#xff1a; 可以更加清晰的发现如何从题意中获得贪心的思路。 如何贪心&#xff1a;局部最优&#xff1a;收集每天的…

Unity中Batching优化的GPU实例化(3)

文章目录 前言一、UNITY_SETUP_INSTANCE_ID(v);二、在UnityInstancing.cginc文件中&#xff0c;看一下Unity这句话做了什么1、使用了该 .cginc 后&#xff0c;会自动预定义该函数2、需要满足GPU实例化条件&#xff0c;才会执行对应语句3、满足GPU实例化后&#xff0c;主要执行的…

【Web】SCU新生赛个人wp及完赛感想

目录 一些碎碎念&#xff1a; Web Guideline 2048 ezupload hardupload ezphp ezweb ezsql webbuilder tarit tarit_revenge VipDinner simplespi 一些碎碎念&#xff1a; scu新生赛是我全心全力打的第二场比赛&#xff0c;历时七天&#xff0c;期间不免煎熬&…

[GPT]Andrej Karpathy微软Build大会GPT演讲(下)--该如何使用GPT助手

该如何使用GPT助手--将GPT助手模型应用于问题 现在我要换个方向,让我们看看如何最好地将 GPT 助手模型应用于您的问题。 现在我想在一个具体示例的场景里展示。让我们在这里使用一个具体示例。 假设你正在写一篇文章或一篇博客文章,你打算在最后写这句话。 加州的人口是阿拉…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-2稳定性分析Stability

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-2稳定性分析Stability 0. 序言1. 稳定的分类2. 稳定的对象3. 稳定的系统4. 系统稳定性的讨论5. 补充内容——Transfer Function(传递函数) - nonzero Initial Condition(非零初始…

C现代方法(第27章)笔记——C99对数学计算的新增支持

文章目录 第27章 C99对数学计算的新增支持27.1 <stdint.h>: 整数类型(C99)27.1.1 <stdint.h>类型27.1.2 对指定宽度整数类型的限制27.1.3 对其他整数类型的限制27.1.4 用于整型常量的宏 27.2 <inttype.h>: 整数类型的格式转换(C99)27.2.1 用于格式指定符的宏…

【设计模式--创建型--建造者模式】

建造者模式 建造者模式概述结构结果优缺点使用场景 将上述案例改为链式调用结果 建造者模式 概述 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 分离了部件的构建&#xff08;由Builder来负责&#xff09;和装配&#xff08;由Direct…

接触刚性环境任务下的机器人力控(阻抗)性能测试

内涵 接触刚性环境任务下的机器人力控&#xff08;阻抗&#xff09;性能测试旨在评估机器人在与刚性物体交互时的性能表现。这种测试通过调整机器人的控制参数&#xff0c;如期望刚度和期望阻尼等&#xff0c;并分析记录的数据&#xff0c;旨在确保机器人能够在执行任务时保持…

类数组对象转为数组的方法

在开发的过程经常会遇到一些类数组对象&#xff0c;例如arguments&#xff0c;类数组对象具有length属性&#xff0c;也可以通过下标访问到对应值&#xff0c;但是不能使用数组的方法&#xff0c;如果将类数组对象转为数组&#xff0c;数组方法可以帮助我们更快实现逻辑&#x…

C++枚举类

枚举 C11有作用域枚举和无作用域枚举 无作用域枚举 特点 全局作用域&#xff1a;无作用域枚举的成员&#xff08;枚举值&#xff09;在包含它们的作用域内是直接可见的&#xff0c;不需要使用枚举类型名称作为前缀。 隐式类型转换&#xff1a;无作用域枚举的成员可以隐式地转换…

机器学习 | Python贝叶斯超参数优化模型答疑

机器学习 | Python贝叶斯超参数优化模型答疑 目录 机器学习 | Python贝叶斯超参数优化模型答疑问题汇总问题1答疑问题2答疑问题3答疑问题汇总 问题1:想问一下贝叶斯优化是什么? 问题2:为什么使用贝叶斯优化? 问题3:如何实现? 问题1答疑 超参数优化在大多数机器学习流水线…

ToolkenGPT:用大量工具增强LLM

深度学习自然语言处理 原创作者&#xff1a;cola 用外部工具增强大型语言模型(LLM)已经成为解决复杂问题的一种方法。然而&#xff0c;用样例数据对LLM进行微调的传统方法&#xff0c;可能既昂贵又局限于一组预定义的工具。最近的上下文学习范式缓解了这一问题&#xff0c;但有…

微信小程序pc端宽高:默认宽高为1024*812,全屏宽高为1920*1032

最近开发调试pc端小程序&#xff0c;想知道默认打开和全屏这两种情况下的小程序宽高&#xff0c;发现了一种方法&#xff1a; 真机运行pc端小程序&#xff0c;点击devTools 在控制台直接打印window对象&#xff0c;可以获取到pc端默认屏幕宽高为1024*812&#xff0c;全屏pc端小…