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 =  9         }
10 
11          HNode(T val)
12 13             data = val;
14             weight = 15             leftNode = 16             rightNode = 17 18 
19         /// <summary>
20         /// 权重
21         </summary>
22         int weight { get; set; }
23 
24         25          内容
26         27         public T data { 28 
29         30          左树
31         32         public HNode<T> leftNode { 33 
34         35          右树
36         37         public HNode<T> rightNode { 38     }

 

 1     2      赫夫曼树
 3      4     <typeparam name="T"></typeparam>
 5     class HTree<T>
 6  7          8          树的头结点
 9         10         public HNode<T> head { 11 
12         13          构造函数
14         15         <param name="val"></param>
16          HTree(T val)
18             head = new HNode<T>(val);
19 20 
21          HTree()
22 23             head = ();
24  构建树结构
27         28         <param name="list"></param>
29         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 = 44                 if (i == 145                 {
46                     先取最小的两个节点
47                     parentNode.leftNode = nodes[];
48                     parentNode.rightNode = nodes[49                     parentNode.weight = nodes[0].weight + nodes[].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                     60 61                         parentNode.rightNode =62                         parentNode.leftNode =63 64                     parentNode.weight = head.weight + nodes[i].weight;
65 66                 head = parentNode;
67             }
68 69 
70         71          先序遍历
72         73         <param name="index"></param>
74         void PreorderTraversal(HNode<T> node)
75 76             递归的终止条件
77             if (head == 78 79                 Console.WriteLine(当前树为空80                 return81 82             if (node != 83 84                 if(node.data != 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",BCDE };
2 HTree<string> tree = new HTree<string>3 tree.build(list);
4 tree.PreorderTraversal(tree.head);

打印结果:

A 
B 
C 3
D 4
E 5

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

 

 

 

 

相关文章

项目中经常遇到CSV文件的读写需求,其中的难点主要是CSV文件...
简介 本文的初衷是希望帮助那些有其它平台视觉算法开发经验的...
这篇文章主要简单记录一下C#项目的dll文件管理方法,以便后期...
在C#中的使用JSON序列化及反序列化时,推荐使用Json.NET——...
事件总线是对发布-订阅模式的一种实现,是一种集中式事件处理...
通用翻译API的HTTPS 地址为https://fanyi-api.baidu.com/api...