什么是赫夫曼树?

赫夫曼树(Huffman Tree)是指给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小。哈夫曼树(也称为最优二叉树)是带权路径长度最短的树,权值较大的结点离根较近。

 1    public class HNode<T>
2 {
3 public HNode()
4 {
5 data = default(T);
6 weight = 0;
7 leftNode = null;
8 rightNode = null;
9 }
10
11 public HNode(T val)
12 {
13 data = val;
14 weight = 0;
15 leftNode = null;
16 rightNode = null;
17 }
18
19 /// <summary>
20 /// 权重
21 /// </summary>
22 public int weight { get; set; }
23
24 /// <summary>
25 /// 内容
26 /// </summary>
27 public T data { get; set; }
28
29 /// <summary>
30 /// 左树
31 /// </summary>
32 public HNode<T> leftNode { get; set; }
33
34 /// <summary>
35 /// 右树
36 /// </summary>
37 public HNode<T> rightNode { get; set; }
38 }
 1    /// <summary>
2 /// 赫夫曼树
3 /// </summary>
4 /// <typeparam name="T"></typeparam>
5 public class HTree<T>
6 {
7 /// <summary>
8 /// 树的头结点
9 /// </summary>
10 public HNode<T> head { get; set; }
11
12 /// <summary>
13 /// 构造函数
14 /// </summary>
15 /// <param name="val"></param>
16 public HTree(T val)
17 {
18 head = new HNode<T>(val);
19 }
20
21 public HTree()
22 {
23 head = new HNode<T>();
24 }
25 /// <summary>
26 /// 构建树结构
27 /// </summary>
28 /// <param name="list"></param>
29 public void build(List<T> list)
30 {
31 //判断是否能构建树结构
32 if (list == null || list.Count <2)
33 throw new ArgumentOutOfRangeException("params error");
34 //分组统计
35 List<HNode<T>> nodes = new List<HNode<T>>();
36 nodes.AddRange(from m in list group m by m into g
37 select new HNode<T> { data = g.Key,weight = g.Count()});
38 //排序
39 nodes = nodes.OrderBy(i => i.weight).ToList();
40
41 for (int i =1; i< nodes.Count; i++)
42 {
43 HNode<T> parentNode = new HNode<T>();
44 if (i == 1)
45 {
46 //先取最小的两个节点
47 parentNode.leftNode = nodes[0];
48 parentNode.rightNode = nodes[1];
49 parentNode.weight = nodes[0].weight + nodes[1].weight;
50 }
51 else
52 {
53 //依次取节点构建树
54 if (head.weight >= nodes[i].weight)
55 {
56 parentNode.leftNode = head;
57 parentNode.rightNode = nodes[i];
58 }
59 else
60 {
61 parentNode.rightNode = head;
62 parentNode.leftNode = nodes[i];
63 }
64 parentNode.weight = head.weight + nodes[i].weight;
65 }
66 head = parentNode;
67 }
68 }
69
70 /// <summary>
71 /// 先序遍历
72 /// </summary>
73 /// <param name="index"></param>
74 public void PreorderTraversal(HNode<T> node)
75 {
76 //递归的终止条件
77 if (head == null)
78 {
79 Console.WriteLine("当前树为空");
80 return;
81 }
82 if (node != null)
83 {
84 if(node.data != null)
85 Console.WriteLine($"{node.data} {node.weight}");
86 PreorderTraversal(node.leftNode);
87 PreorderTraversal(node.rightNode);
88 }
89 }
90 }

测试代码:

1 List<string> list = new List<string>() { "A","B", "B", "C", "C", "C", "D", "D", "D", "D", "E", "E", "E", "E", "E" };
2 HTree<string> tree = new HTree<string>();
3 tree.build(list);
4 tree.PreorderTraversal(tree.head);

打印结果:

A 1
B 2
C 3
D 4
E 5

用这个例子现在我们看下构建的二叉树结构:


C#数据结构-赫夫曼树的更多相关文章

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

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

  2. 【数据结构】赫夫曼树的实现和模拟压缩(C++)

    赫夫曼(Huffman)树,由发明它的人物命名,又称最优树,是一类带权路径最短的二叉树,主要用于数据压缩传输. 赫夫曼树的构造过程相对比较简单,要理解赫夫曼数,要先了解赫夫曼编码. 对一组出现频率不同 ...

  3. Android版数据结构与算法(七):赫夫曼树

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 近期忙着新版本的开发,此外正在回顾C语言,大部分时间没放在数据结构与算法的整理上,所以更新有点慢了,不过既然写了就肯定尽力将这部分完全整理好分享出 ...

  4. javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题

    赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...

  5. 【算法】赫夫曼树(Huffman)的构建和应用(编码、译码)

    参考资料 <算法(java)>                           — — Robert Sedgewick, Kevin Wayne <数据结构>       ...

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

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

  7. puk1521 赫夫曼树编码

    Description An entropy encoder is a data encoding method that achieves lossless data compression by ...

  8. 数据结构-哈夫曼树(python实现)

    好,前面我们介绍了一般二叉树.完全二叉树.满二叉树,这篇文章呢,我们要介绍的是哈夫曼树. 哈夫曼树也叫最优二叉树,与哈夫曼树相关的概念还有哈夫曼编码,这两者其实是相同的.哈夫曼编码是哈夫曼在1952年 ...

  9. 高级数据结构---赫(哈)夫曼树及java代码实现

    我们经常会用到文件压缩,压缩之后文件会变小,便于传输,使用的时候又将其解压出来.为什么压缩之后会变小,而且压缩和解压也不会出错.赫夫曼编码和赫夫曼树了解一下. 赫夫曼树: 它是一种的叶子结点带有权重的 ...

随机推荐

  1. FL studio系列教程(十八):FL Studio输出监视面板讲解

    在FL Studio编曲制作软件中输出监视器面板主要的功能是监视输出电平和波形以及频谱.下面大家就跟小编一起来认识下什么是FL Studio监视面板以及它的一些特征吧! 1.首先,我们来看一下输出监视 ...

  2. 永别了,Dota2!

    永别了,Dota2 .输了游戏,我还有人生! 游戏中,总有那些喷子,自己玩的不好,经常说人家! 和大便打架,即使赢了,身上也非常臭! 所以对于这种人,敬而远之即可!不吵不闹,默默把锅扛起!赢了,就好说 ...

  3. Spring MVC系列-(5) AOP

    5 AOP 5.1 什么是AOP AOP(Aspect-Oriented Programming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的 ...

  4. 2017年第八届蓝桥杯【C++省赛B组】B、C、D、H 题解

    可能因为我使用暴力思维比较少,这场感觉难度不低. B. 等差素数列 #暴力 #枚举 题意 类似:\(7,37,67,97,127,157\) 这样完全由素数组成的等差数列,叫等差素数数列. 上边的数列 ...

  5. PyQt(Python+Qt)学习随笔:QAbstractScrollArea的用途

    老猿Python博文目录 老猿Python博客地址 QAbstractScrollArea部件提供了一个带有按需滚动条的滚动区域. QAbstractScrollArea是滚动区域的低级抽象.该区域提 ...

  6. PyQt(Python+Qt)学习随笔:clicked和clicked(bool)信号连接同名函数出现的问题

    在Qt中,控件中的clicked()信号和clicked(bool)信号是两个不同的信号,映射槽函数时,clicked()信号映射到的槽函数是不带参的,clicked(bool)信号映射到的槽函数是带 ...

  7. RedHat-Linux操作指令第1篇

    不同的linux系统切换方式会稍有一点差别 从图形界面切换到字符界面:Alt+F(1-8) 或者 Alt+Ctrl+Shift+F(1-8) 从字符界面切换回图形界面:Alt+F7 字符界面启动到图形 ...

  8. [GYCTF2020]Blacklist

    这题是用堆叠注入,同时也是借这题记录一下CTF中堆叠注入的一些骚操作 以下部分内容转载大佬的文章 show databases; 获取数据库名 show tables; 获取表名 show colum ...

  9. 性能测试基础——(MEN)

    关于内存在一块其实我并不是很想拿出来说,一般情况下内存这一块都是可优化的,可以通过硬件资源或者调整一些系统或者应用系统的参数配置来进行优化. 很多同僚问到了"内存泄漏"和" ...

  10. SQL直接生成实体属性,简单粗暴型

    在java开发中,不可避免的要碰到根据表生成对应的实体,这个过程是比较机器且繁琐的,我也用过一些逆向工程的工具,比如IDEA自带的生成实体,还有网上开源的工具,用起来也是可以的. 我现在开发用的持久层 ...