C#数据结构-赫夫曼树
什么是赫夫曼树?
赫夫曼树(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#数据结构-赫夫曼树的更多相关文章
- Java数据结构和算法(四)赫夫曼树
Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...
- 【数据结构】赫夫曼树的实现和模拟压缩(C++)
赫夫曼(Huffman)树,由发明它的人物命名,又称最优树,是一类带权路径最短的二叉树,主要用于数据压缩传输. 赫夫曼树的构造过程相对比较简单,要理解赫夫曼数,要先了解赫夫曼编码. 对一组出现频率不同 ...
- Android版数据结构与算法(七):赫夫曼树
版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 近期忙着新版本的开发,此外正在回顾C语言,大部分时间没放在数据结构与算法的整理上,所以更新有点慢了,不过既然写了就肯定尽力将这部分完全整理好分享出 ...
- javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题
赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...
- 【算法】赫夫曼树(Huffman)的构建和应用(编码、译码)
参考资料 <算法(java)> — — Robert Sedgewick, Kevin Wayne <数据结构> ...
- 赫夫曼树JAVA实现及分析
一,介绍 1)构造赫夫曼树的算法是一个贪心算法,贪心的地方在于:总是选取当前频率(权值)最低的两个结点来进行合并,构造新结点. 2)使用最小堆来选取频率最小的节点,有助于提高算法效率,因为要选频率最低 ...
- puk1521 赫夫曼树编码
Description An entropy encoder is a data encoding method that achieves lossless data compression by ...
- 数据结构-哈夫曼树(python实现)
好,前面我们介绍了一般二叉树.完全二叉树.满二叉树,这篇文章呢,我们要介绍的是哈夫曼树. 哈夫曼树也叫最优二叉树,与哈夫曼树相关的概念还有哈夫曼编码,这两者其实是相同的.哈夫曼编码是哈夫曼在1952年 ...
- 高级数据结构---赫(哈)夫曼树及java代码实现
我们经常会用到文件压缩,压缩之后文件会变小,便于传输,使用的时候又将其解压出来.为什么压缩之后会变小,而且压缩和解压也不会出错.赫夫曼编码和赫夫曼树了解一下. 赫夫曼树: 它是一种的叶子结点带有权重的 ...
随机推荐
- 巧用Beyond Compare帮你更好校对文稿
我们平常所说的校对工作,大多数指的是书本.文章出版前的对其进行的原稿比对工作.该工作要求极为细致,校对者需对文稿中的标点.编号.序号等细微部分进行认真比对,以保证出版物的质量.其实我们在日常的学习工作 ...
- FL Studio中echo的延迟作用
今天来一起研究FL Studio的Echo Delay的作用,Echo Delay可以从MIDI输入创建回声,并允许我们通过音量,声像,切除和共振,音高和时间来操纵延迟. 图1:Echo Dealy ...
- nginx介绍及常用功能
什么是nginx nginx跟Apache一样,是一个web服务器(网站服务器),通过HTTP协议提供各种网络服务. Apache:重量级的,不支持高并发的服务器.在Apache上运行数以万计的并发访 ...
- [Python]环境配置之pip加速
背景 学习 Python 的话,仅掌握标准库是远不够的,有很多好用的第三方库我们也需要用到的,比如,由鼎鼎大名的 K 神开发的爬虫必不可少的 requests 库,一般都是必装的库吧.安装第三方库当然 ...
- jdk1.8hashmap常见的面试问题
1.HashMap原理,内部数据结构? 底层使用哈希表(数组加链表)来存储,链表过长会将链表转成红黑树,以实现在O(logn)时间复杂度内查找 2.讲一下HashMap中的put方法过程? 对key求 ...
- How tomcat works(深入剖析tomcat)servlet容器
How tomcat works (5)servlet容器阅读笔记 第四章阅读了tomcat默认连接器的实现,当时connector中的使用的容器是自定义的容器,也是非常之简单奥,一个人就干完了所有的 ...
- vue-父子组件传参以及无限级评论
vue父子组件的使用 <template> <div> <zi :data="data" /> </div> </templa ...
- mongo聚合操作
1 mongodb的聚合是什么 聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组.过滤等功能,然后经过一系列的处理, ...
- java并发编程实战《一》可见性、原子性和有序性
可见性.原子性和有序性问题:并发编程Bug的源头 核心矛盾:CPU.IO.内存三者之间的速度差异. 为了合理利用 CPU 的高性能,平衡这三者的速度差异,计算机体系结构.操作系统.编译程序都做出了贡献 ...
- PyQt(Python+Qt)学习随笔:通过QMainWindow的resizeDocks方法调整QDockWidget停靠窗大小
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 QMainWindow的resizeDocks用于将QMainWind ...