构建哈夫曼树及求它的带权路径长度_使用顺序结构来实现哈夫曼树,并求出最小带权路径长度_可乐学算法的博客-程序员秘密

技术标签:   哈夫曼树  

给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。要构成哈夫曼树,值比较大的叶子节点高度越低越好。

(1) 将n个权值看出n颗只有根节点的树,构建n颗树。
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)(3)步n-1遍,最后森林中只有一棵树,这棵树就是哈夫曼树。
(5)直接用递归求它的带权路径长度即可。

java参考代码:


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Main
{
    
	public static void main(String[] args) 
	{
    
		Scanner sc=new Scanner(System.in);
		int n = sc.nextInt();
		List<Tree> ts=new ArrayList<Tree>();
		//构建n颗只有根节点的树
		for(int i=0;i<n;i++)
			ts.add(new Tree(sc.nextInt()));
		//进行n-1次,删除最小的两棵树,合并两棵树并加进去
		for(int i=0;i<n-1;i++)
			removeAndAdd(ts);
		//求带权路径长度
		int ans=getNum(ts.get(0),0);
		System.out.println(ans);
		
	}
	
	private static int getNum(Tree tree,int n) 
	{
    
		if(tree.left==null&&tree.right==null)
			return tree.data*n;
		return getNum(tree.left, n+1)+getNum(tree.right, n+1);		
	}

	private static void removeAndAdd(List<Tree> ts) 
	{
    
		int min1=Integer.MAX_VALUE;
		int min2=Integer.MAX_VALUE;
		int inx1=-1;
		int inx2=-1;
		//找出两个最小值
		for(int i=0;i<ts.size();i++)
		{
    
			Tree t=ts.get(i);
			if(t.data<min1)
			{
    
				min1=t.data;
				inx1=i;
			}
			else if(t.data<min2)
			{
    
				min2=t.data;
				inx2=i;
			}
		}
		
		//删除两颗最小的数,合并两棵树,并加入
		Tree t1=ts.get(inx1);
		Tree t2=ts.get(inx2);
		Tree t=new Tree(t1.data+t2.data);
		t.left=t1;
		t.right=t2;
		ts.remove(t1);
		ts.remove(t2);
		ts.add(t);
		
	}

	
}

class Tree
{
    
	int data;
	Tree left;
	Tree right;
	Tree(int data) {
    
		super();
		this.data = data;
	}

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

智能推荐

【LwIP】让LwIP拥有PING其他设备的能力_lwip ping_RiverFormSky的博客-程序员秘密

本文的前提是单片机的LWIP已经跑起来了,能够被外部设备ping通,在此基础上,新增让单片机ping外部设备的功能。首先,我们需要创建ICMP控制块,在mian函数前创建一次即可。struct raw_pcb *ping_pcb;extern unsigned char pingEchoReply;uint8_t icmp_pcb_init(void){ ping_pcb = raw...

关于STM32H743 recv()数据错误的问题分析_躺着的树懒的博客-程序员秘密

问题描述中位机使用TCP方式接收数据时可能出现数据错误,出错概率极高,大约接收300字节内必出。错误如下:最终结论中位机使用ST厂商自带的HAL库,该源代码在关闭网络接收的DCache(数据缓存)功能时有bug,可能导致部分区域的DCache未被关闭,从而导致TCP接收时可能从不正确的数据来源区拷贝数据,从而出错。软件环境HAL库版本号: STM32H7xx HAL V1.9.0STM32CubeMX版本: 6.1.0中位机MCU: STM32H743LWIP版本:.

oracle11g_基表I_DEPENDENCY1之move tablespace移动表空间到非system__clg10051的博客-程序员秘密

老外的贴子,关于在不同版本oracle移动基表自system表空间到非system表空间一些研究http://www.ora600.be/ora600-blog/**************我的测试*************...

油炸食品的最佳用油:米糠油_上海依阳的博客-程序员秘密

摘要:本文详细介绍了米糠油作为最佳油炸用油的各种特点,但更重要的是建议采用真空油炸方法,更能发挥米糠油的优势。

【文章整理】CVPR 图像文本生成/GAN 方向文章概要整理_nymph_h的博客-程序员秘密

Event-based High Dynamic Range Image and Very High Frame Rate Video Generation using Conditional Generative Adversarial Networks使用有条件的GAN进行基于事件的高动态性区域图像和极高帧率视频生成摘要: 使用Conditional GAN实现了基于事件摄像机的从一个数...

数据结构实验报告-实验五-构造二叉树和二叉树的层序遍历_哆啦一泓的博客-程序员秘密

实验五 构造二叉树和二叉树的层序遍历一、实验描述1. 构造二叉树:给出一棵二叉树的先序(或后序)遍历结果,以及中序遍历结果,如何构造这棵树?假定遍历结果以数组方式输入,请写出相应函数,判断是否存在生成同样遍历结果的树,如果存在,构造这棵树。2. 二叉树的层序遍历:使用队列作为辅助存储,按树的结点的深度,从根开始依次访问所有结点。二、实验分析(1)构造二叉树:①根据...

随便推点

SQL性能--left join和inner join的运行速度与效率_innerjoin和leftjoin效率_striver_dl的博客-程序员秘密

①大家都知道,sql尽量使用数据量小的表做主表,这样效率高,如果使用数据量大的表做主表,此时使用left join 就会比较慢,即使关联条件有索引。但如果使用inner join速度就较快。因为inner join 在执行的时候回自动选择最小的表做基础表,效率高,总之相比之下inner join不管从效率还是速度上都优于left join,毕竟left join 会多一部分逻辑运算②选择inner join还有个好处,不会产生null,有些表我们在定义的时候某些字段不允许存在null,如果用left jo

Java内存异常原理与实践_大碍桃花开的博客-程序员秘密

JVM系列之实战内存溢出异常实战内存溢出异常大家好,相信大部分Javaer在code时经常会遇到本地代码运行正常,但在生产环境偶尔会莫名其妙的报一些关于内存的异常,StackOverFlowError,OutOfMemoryError异常是最常见的。今天就基于上篇文章JVM系列之Java内存结构详解讲解...

yarn/historyserver 无法查看历史任务_向前走呀不回头的博客-程序员秘密

在使用http://node01:19888/jobhistory/app 来查看历史任务时,发现看不到历史任务。经过查找,发现是配置文件少了一项东西,是要在mapred-site.xml文件中加入如下配置即可路径为$HADOOP_HOME/etc/hadoop/mapred-site.xml添加的配置为 &lt;property&gt; ...

Android drawable微技巧_weixin_34363171的博客-程序员秘密

家都知道,在Android项目当中,drawable文件夹都是用来放置图片资源的,不管是jpg、png、还是9.png,都可以放在这里。除此之外,还有像selector这样的xml文件也是可以放在drawable文件夹下面的。但是如果你现在使用Android Studio来新建一个项目,你会发现有如下的目录结构:嗯?怎么会有这么多mipmap开头的文件夹,而且它们的命名规则和drawa...

统计英文句子中有多少个英文单词 单词之间用空格分开_赖卓成的博客-程序员秘密

#include&amp;lt;iostream&amp;gt;#include&amp;lt;string.h&amp;gt;using namespace std;void main(){ int i,j=0; char a[100]; cout&amp;lt;&amp;lt;&quot;请输入一个英文句子&quot;&amp;lt;&amp;lt;endl; gets(a); puts(a); for(i=0;i&amp;lt;strlen(a);i++) { if(a[i]==...

推荐文章

热门文章

相关标签