什么是赫夫曼树?

赫夫曼树(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. Vegas让人物回眸更有韵味的方法分享

    "回眸一笑百媚生,六宫粉黛无颜色",是白居易在<长恨歌>中描述杨贵妃美貌的名句,这一句运用夸张的手法,反映了杨贵妃回眸时的娇媚横生,百般娇媚. 接下来,小编就教你用视频 ...

  2. 基于gin的golang web开发:永远不要相信用户的输入

    作为后端开发者我们要记住一句话:"永远不要相信用户的输入",这里所说的用户可能是人,也可能是另一个应用程序."永远不要相信用户的输入"是安全编码的准则,也就是说 ...

  3. DIV滚动条设置添加 CSS滚动条显示与滚动条隐藏

    <!DOCTYPE html> <html> <head> <meta charset="gb2312" /> <title& ...

  4. 【数据结构模版】可持久化线段树 && 主席树

    浙江集训Day4,从早8:00懵B到晚21:00,只搞懂了可持久化线段树以及主席树的板子.今天只能记个大概,以后详细完善讲解. 可持久化线段树指的是一种基于线段树的可回溯历史状态的数据结构.我们想要保 ...

  5. vue前端静态页面Github Pages线上预览实现

    一.前期准备之项目编译 此处记录如何解决vue2.0 打包之后,打开index.html出现空白页的问题,附上@参考地址 打包之前修改三个文件 第一步,找到build文件,在webpack.prod. ...

  6. @Async失效之谜

    @Async如何使用 异步的方法上加上@Async异步注解 启动类中需要加上@EnableAsync才有效 使用时类似于下列函数: new Thread(()-> System.out.prin ...

  7. synchronized底层揭秘

    前言 上篇文章我们从硬件级别探索,对可见性和有序性的认识上升了一个高度,却迟迟没有介绍原子性的解决方案. 今天我们就来聊一聊原子性的解决方案,锁. 引入锁机制,除了可以保证原子性,同时也可以保证可见性 ...

  8. 【译】理解Rust中的局部移动

    原文标题:Understanding Partial Moves in Rust 原文链接:https://whileydave.com/2020/11/30/understanding-partia ...

  9. NDK&JNI开发总结

    NDK&JNI开发总结 简介 附个不错的博客 https://www.jianshu.com/p/87ce6f565d37 在Android Framework中,需要提供一种媒介或 桥梁,将 ...

  10. IDEA2020.2.4最新激活教程,有效期到2089

    前言 昨天又有好多粉丝反馈Idea失效过期,也有群里的小伙伴私聊问我,最新的Idea2020.2.4 版本要如何激活? 于是自己在网上搜罗了各种注册码.激活码,均以失败告终,有的虽然当时成功了,当时很 ...