[问题描述]

根据给定的若干权值可以构造出一颗哈夫曼树。构造的哈夫曼树可能不唯一,但是按照下面的选取原则所构造出来的哈夫曼树应该是唯一的。

(1)每次选取优先级最低的两个结点,优先级最低的作为左子树,优先级高的作为右子树;

(2)结点优先级大小的比较首先比较它们的权值,权值大的优先级高,权值小的优先级低,权值相等的按照位置关系来比较,位置在前面的优先级低,位置在后面的优先级高。

(3)增加的新结点位置依次往后。

根据你所构造的哈夫曼树来设计每个权值的哈夫曼编码(左子树0右子树1),并计算该哈夫曼树的WPL值。

[输入]

包含多组数据

每组数据包含2行,第一行输入权值个数n(0<n<20),第2行为顺序输入的n个权值,均为整数(小于100),

[输出]

对于每组数据,输出n+1行,前面n行为每个权值所对应的赫夫曼编码(按照输入顺序给出),第n+1行用来输出你所构造的哈夫曼树的WPL值。

[样例输入]

5

11 4 2 5 7

6

2 3 4 7 8 9

[样例输出]

11

011

010

00

10

64

1110

1111

110

00

01

10

80

PS:

他这个是特别版的哈夫曼树,相同的权值时,位置靠左面的会小,

所以你查询的时候,先靠左查询,其他不懂得在评论

哈夫曼树相关的几个名词

路径:在一棵树中,一个结点到另一个结点之间的通路,称为路径。图 1 中,从根结点到结点 a 之间的通路就是一条路径。

路径长度:在一条路径中,每经过一个结点,路径长度都要加 1 。例如在一棵树中,规定根结点所在层数为1层,那么从根结点到第 i 层结点的路径长度为 i - 1 。图 1 中从根结点到结点 c 的路径长度为 3。

结点的权:给每一个结点赋予一个新的数值,被称为这个结点的权。例如,图 1 中结点 a 的权为 7,结点 b 的权为 5。

结点的带权路径长度:指的是从根结点到该结点之间的路径长度与该结点的权的乘积。例如,图 1 中结点 b 的带权路径长度为 2 * 5 = 10 。

树的带权路径长度为树中所有叶子结点的带权路径长度之和。通常记作 “WPL” 。例如图 1 中所示的这颗树的带权路径长度为:

WPL = 7 * 1 + 5 * 2 + 2 * 3 + 4 * 3



图1 哈夫曼树

什么是哈夫曼树

当用 n 个结点(都做叶子结点且都有各自的权值)试图构建一棵树时,如果构建的这棵树的带权路径长度最小,称这棵树为“最优二叉树”,有时也叫“赫夫曼树”或者“哈夫曼树”。

在构建哈弗曼树时,要使树的带权路径长度最小,只需要遵循一个原则,那就是:权重越大的结点离树根越近。在图 1 中,因为结点 a 的权值最大,所以理应直接作为根结点的孩子结点。

构建哈夫曼树的过程

对于给定的有各自权值的 n 个结点,构建哈夫曼树有一个行之有效的办法:

在 n 个权值中选出两个最小的权值,对应的两个结点组成一个新的二叉树,且新二叉树的根结点的权值为左右孩子权值的和;

在原有的 n 个权值中删除那两个最小的权值,同时将新的权值加入到 n–2 个权值的行列中,以此类推;

重复 1 和 2 ,直到所以的结点构建成了一棵二叉树为止,这棵树就是哈夫曼树。



图 2 哈夫曼树的构建过程

图 2 中,(A)给定了四个结点a,b,c,d,权值分别为7,5,2,4;第一步如(B)所示,找出现有权值中最小的两个,2 和 4 ,相应的结点 c 和 d 构建一个新的二叉树,树根的权值为 2 + 4 = 6,同时将原有权值中的 2 和 4 删掉,将新的权值 6 加入;进入(C),重复之前的步骤。直到(D)中,所有的结点构建成了一个全新的二叉树,这就是哈夫曼树。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner; public class Demo10哈弗们数 {
public static class TreeNode implements Comparable<TreeNode>{
int val;
boolean bool;
TreeNode left;
TreeNode right; TreeNode(int x) {
val = x;
} @Override
public int compareTo(TreeNode o) { // TODO 自动生成的方法存根 if(this.val>o.val){
return 1;
}
else if(this.val<o.val){
return -1;
}
else {
if(this.bool){
return 1;
}
else if(o.bool){
return -1;
} }
return 0;
}
} static TreeNode tree = new TreeNode(0);
static ArrayList<TreeNode> list = new ArrayList<TreeNode>(); static ArrayList<String> list1 = new ArrayList<String>(); public static void main(String[] args) { Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
tree = new TreeNode(0);
list = new ArrayList<TreeNode>();
list1 = new ArrayList<String>();
int sum = 0; int n = sc.nextInt();
int[] num = new int[n];
for (int i = 0; i < n; i++) { num[i] = sc.nextInt();
TreeNode tree11 = new TreeNode(num[i]);
list.add(tree11);
}
Collections.sort(list);
// Arrays.sort(num);
madetree();
for (int i = 0; i < num.length; i++) {
findtree(tree, num[i], "");
System.out.println( list1.get(i));
sum+=num[i]*list1.get(i).length(); }
System.out.println(sum);
// System.out.println(list1.size());
}
} public static void findtree(TreeNode node, int n, String s) {
if (node.val == n && !node.bool) {
list1.add(s);
return;
}
if (node.left != null)
findtree(node.left, n, s + "0");
if (node.right != null)
findtree(node.right, n, s + "1"); return; } public static void madetree() {
boolean flag = true;
while (list.size() != 1) {
Collections.sort(list);
// int a = list.get(0);
// int b = list.get(1); // if (a > b) {
// int temp = a;
// a = b;
// b = temp;
// }
TreeNode treeleft = list.get(0);
TreeNode treeright = list.get(1);
list.remove(0);
list.remove(0);
TreeNode treemid = new TreeNode(treeleft.val+treeright.val);
treemid.left = treeleft;
treemid.right = treeright;
treemid.bool = true;
tree = treemid;
// if (flag) {
// flag = false;
//
// TreeNode treeleft1 = null;
// TreeNode treeright1 = null;
//
// if (treemid.val > tree.val) {
// treeleft1 = tree;
// treeright1 = treemid;
//
// } else {
// treeleft1 = treemid;
// treeright1 = tree;
// }
// TreeNode treemid1 = new TreeNode(tree.val + treemid.val);
// treemid1.left = treeleft1;
// treemid1.right = treeright1;
// treemid1.bool = true;
// if (tree.val != 0) {
// tree = treemid1;
// } else {
// tree = treemid;
// }
// } list.add(tree);
}
} }

Java实现WUST 1002: 哈夫曼树的更多相关文章

  1. (哈夫曼树)HuffmanTree的java实现

    参考自:http://blog.csdn.net/jdhanhua/article/details/6621026 哈夫曼树 哈夫曼树(霍夫曼树)又称为最优树. 1.路径和路径长度在一棵树中,从一个结 ...

  2. 哈夫曼树(三)之 Java详解

    前面分别通过C和C++实现了哈夫曼树,本章给出哈夫曼树的java版本. 目录 1. 哈夫曼树的介绍 2. 哈夫曼树的图文解析 3. 哈夫曼树的基本操作 4. 哈夫曼树的完整源码 转载请注明出处:htt ...

  3. 赫夫曼树JAVA实现及分析

    一,介绍 1)构造赫夫曼树的算法是一个贪心算法,贪心的地方在于:总是选取当前频率(权值)最低的两个结点来进行合并,构造新结点. 2)使用最小堆来选取频率最小的节点,有助于提高算法效率,因为要选频率最低 ...

  4. Java数据结构和算法(四)赫夫曼树

    Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...

  5. 20172332 2017-2018-2 《程序设计与数据结构》Java哈夫曼编码实验--哈夫曼树的建立,编码与解码

    20172332 2017-2018-2 <程序设计与数据结构>Java哈夫曼编码实验--哈夫曼树的建立,编码与解码 哈夫曼树 1.路径和路径长度 在一棵树中,从一个结点往下可以达到的孩子 ...

  6. Java中的哈夫曼树

    package com.ietree.basic.datastructure.tree; import java.util.ArrayDeque; import java.util.ArrayList ...

  7. java实现哈弗曼树和哈夫曼树压缩

    本篇博文将介绍什么是哈夫曼树,并且如何在java语言中构建一棵哈夫曼树,怎么利用哈夫曼树实现对文件的压缩和解压.首先,先来了解下什么哈夫曼树. 一.哈夫曼树 哈夫曼树属于二叉树,即树的结点最多拥有2个 ...

  8. 哈夫曼树的介绍 ---java实现

    一.     什么是哈夫曼树 是一种带权路径长度最短的二叉树,也称最优二叉树 带权路径长度:WPL=(W1*L1+W2*L2+W3*L3+...+ Wn*Ln) N个权值Wi(i=1,2,...n)构 ...

  9. java实现哈夫曼树进行文件加解压

    目录 1.哈夫曼树简述 2.构造树的节点 3.构造哈夫曼树的类(压缩) 4.构造哈夫曼树的类(解压) 5.整体工程文件(包括测试类) 6.结果 7.参考链接 1.哈夫曼树简述 给定n个权值作为n个叶子 ...

随机推荐

  1. 使用JDBC操作MySQL

    使用JDBC操作MySQL 步骤 加载驱动 连接数据库 操作数据库(增删改查) 关闭结果集,操作,数据库 准备工作 java连接MySQL的jar包 加载数据库驱动 public class Load ...

  2. python解析excel中图片+提取图片

    解析表格是常用的技术.但是有些表各里面有图片怎么办?我想获得表格里面的图片,值得注意的是,图片没有位置信息,所以最好给图片进行编号,编号代表位置. 下面附上提取表格里面图片的代码.只要输出表格地址,和 ...

  3. java -类加载器与反射

    类加载器 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. l  加载 就是指将class文件读入内存,并为之创建一个Class ...

  4. MFC带参数启动指令发送与接收

    MFC带参数启动指令发送与接收 发送 使用ShellExecute函数打开文件或执行程序. 函数原型: HINSTANCE ShellExecute( _In_opt_ HWND hwnd,//父窗口 ...

  5. Oracle 大数据查询优化方法

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  6. 9.1 Go 反射

    9.1 Go 反射 反射:可以在运行时,动态获取变量的信息,比如变量的类型,类别 1.对于结构体变量,还可以获取到结构体的字段,方法 2.实现这个功能的是 reflect包 reflect.TypeO ...

  7. Django之请求生命周期

    settings.py中间件执行 自定义中间件的配置: (1)任意新建一个py文件,导入模块from django.utils.deprecation import MiddlewareMixin ( ...

  8. 关于mysql中的锁总结

    一.锁的基本信息: 共享锁(s):又称读锁.允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁.若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁 ...

  9. 移除项目中的UIWebView

    1,AFN升级4.0 2,代码中搜索UIWebView移除相关文件 3,检查库是否使用的UIWebView 参考 https://www.jianshu.com/p/3a645500d461

  10. 永久关闭windows更新步骤

    在搜索“web和windows”框中输入“服务” 在搜索结果中点击第一个,那个图标像齿轮的那个!如下图. 在打开的“服务”窗口中,我们找到windows update   找到”windows upd ...