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代码实现
我们经常会用到文件压缩,压缩之后文件会变小,便于传输,使用的时候又将其解压出来.为什么压缩之后会变小,而且压缩和解压也不会出错.赫夫曼编码和赫夫曼树了解一下. 赫夫曼树: 它是一种的叶子结点带有权重的 ...
随机推荐
- H5时代leaflet中还在用DivIcon?
前段时间写了篇<leaflet如何加载10万数据>的文章,有同学反应其中的Canvas-Markers插件不支持DivIcon.我们今天就来聊一聊,为什么这个插件不支持DivIcon,以及 ...
- 庐山真面目之四微服务架构Consul和Ocelot简单版本实现
庐山真面目之四微服务架构Consul和Ocelot简单版本实现 一.简介 在上一篇文章<庐山真面目之三微服务架构Consul简单版本实现>中,我们已经探讨了如何搭建基于Consu ...
- jenkins master/slave模式
master是主机,只有master装jenkins slave是小弟机无需装jenkins,主要执行master分配的任务 一.新建slave 1.新建slave的方法:点击magian jenki ...
- 通过jquery 获取下拉列表中选中的值对应的value
<div class="col-sm-9"> <select id="device-type" class="form-contro ...
- 提交的忠金融的bug
- linux设置共享文件夹 - samba
安装samba sudo apt-get install samba 配置 /etc/samba/smb.conf 的global模块添加security = user 最下加入 [share] pa ...
- cobbler 装机服务
一.Cobbler 安装 $ yum install -y epel-release $ yum install -y cobbler cobbler-web pykickstart debmirro ...
- JS基础入门,知识点总结归纳图
- LeetCode 010 Regular Expression Matching
题目描述:Regular Expression Matching Implement regular expression matching with support for '.' and '*' ...
- C和指针课后练习题4
1.下面表达式是否合法?如果合法,他执行什么任务? 3* x * x - 4 * x + 6; 合法;他只是执行了表达式求值,但是他的结果并不存于任何地方. 2.赋值语句的语法? 数据类型 变量名 = ...