IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构(十二)——赫夫曼树 -> 正文阅读

[数据结构与算法]数据结构(十二)——赫夫曼树

给定 n 个权值作为 n 个叶子结点, 构造一棵二叉树, 若该树的带权路径长度(wpl)达到最小, 称这样的二叉树为最优二叉树, 也称为霍夫曼树(Huffman Tree)。

在正式介绍霍夫曼树之前,先介绍一下带权路径长度WPL(weighted path
length):树的带权路径长度规定为所有叶子结点的带权路径长度之和, 记为 WPL ,权值越大的结点离根结点越近的二叉树才是最优二叉树。

路径和路径长度: 在一棵树中, 从一个结点往下可以达到的孩子或孙子结点之间的通路, 称为路径。 通路中分支的数目称为路径长度。 若规定根结点的层数为 1, 则从根结点到第 L 层结点的路径长度为 L-1

结点的权及带权路径长度: 若将树中结点赋给一个有着某种含义的数值, 则这个数值称为该结点的权。 结点的带权路径长度为: 从根结点到该结点之间的路径长度与该结点的权的乘积

比如下图所示三棵树的WPL分别是
在这里插入图片描述
规定的4个叶子节点,其权值分别是13,7,8,3,其wpl最小是59,WPL最小的就是赫夫曼树,其特点是权值较大的节点离根节点较近

实现赫夫曼树的步骤

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

赫夫曼树代码实现:

public class HuffmanTreeDemo {

	public static void main(String[] args) {
		int[] arr = {13, 7, 8, 3};
		Node root = creatHuffmanTree(arr);

		//
		preOrder(root);
	}
	
	public static void preOrder(Node root){
		if(root != null) {
			root.preOrder();
		}else {
			System.out.println("null");
		}
	}
	
	//创建赫夫曼树的方法
	public static Node creatHuffmanTree(int[] arr) {
		ArrayList<Node> nodes = new ArrayList<Node>();
		for(int value : arr){
			nodes.add(new Node(value));
		}
		
		while(nodes.size() > 1) {
			//排序,从小到大
			Collections.sort(nodes);
			System.out.println(nodes);
			
			//取出最小的节点
			Node leftNode = nodes.get(0);
			//取出第二小的节点
			Node rightNode = nodes.get(1);
			//构建新的
			Node parent = new Node(leftNode.value + rightNode.value);
			parent.left = leftNode;
			parent.right = rightNode;
			
			//从ArrayList中删除旧的加入新的
			nodes.remove(leftNode);
			nodes.remove(rightNode);
			nodes.add(parent);
		}
		
		//返回赫夫曼树的根节点
		return nodes.get(0);
	}

}

//创建节点类
//为了让Node对象支持排序 Collection集合排序
//让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;
	}
	
	
	
}

实现结果检验,使用前序遍历,可以验证结果正确
在这里插入图片描述

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-18 12:56:50  更:2021-08-18 12:58:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:54:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码