C#使用哈夫曼编码实现压缩与解压

简介: C#使用哈夫曼编码实现压缩与解压

哈夫曼编码是一种基于字符出现频率的最优前缀编码方式,广泛应用于数据压缩领域。下面我将给出一个简单的C#实现哈夫曼编码(压缩)和解压缩的示例,包括构建哈夫曼树、编码和解码过程:

Csharp

1using System;
2using System.Collections.Generic;
3
4// 定义节点类
5public class Node : IComparable<Node>
6{
7    public char Value { get; set; } // 节点值,如果是叶子节点则是字符
8    public int Frequency { get; set; } // 字符出现频率
9    public Node Left { get; set; } 
10    public Node Right { get; set; }
11    
12    public Node(char value, int frequency)
13    {
14        Value = value;
15        Frequency = frequency;
16    }
17
18    public int CompareTo(Node other)
19    {
20        return this.Frequency.CompareTo(other.Frequency);
21    }
22}
23
24public static class HuffmanCoding
25{
26    // 构建哈夫曼树
27    public static Node BuildHuffmanTree(Dictionary<char, int> frequencies)
28    {
29        var queue = new PriorityQueue<Node>(new List<Node>(frequencies.Select(x => new Node(x.Key, x.Value))));
30        while (queue.Count > 1)
31        {
32            var left = queue.Dequeue();
33            var right = queue.Dequeue();
34            
35            var newNode = new Node('\0', left.Frequency + right.Frequency);
36            newNode.Left = left;
37            newNode.Right = right;
38            
39            queue.Enqueue(newNode);
40        }
41        return queue.Dequeue();
42    }
43
44    // 从哈夫曼树生成编码字典
45    public static Dictionary<char, string> GenerateCodes(Node node, string codeSoFar = "", Dictionary<char, string> codes = null)
46    {
47        if (codes == null) codes = new Dictionary<char, string>();
48        
49        if (node.Left == null && node.Right == null) // 叶子节点
50        {
51            codes[node.Value] = codeSoFar;
52            return codes;
53        }
54
55        GenerateCodes(node.Left, codeSoFar + "0", codes);
56        GenerateCodes(node.Right, codeSoFar + "1", codes);
57
58        return codes;
59    }
60
61    // 压缩方法
62    public static string Compress(string input, Dictionary<char, string> huffmanCodes)
63    {
64        var compressedData = new StringBuilder();
65        foreach (char c in input)
66        {
67            compressedData.Append(huffmanCodes[c]);
68        }
69        return compressedData.ToString();
70    }
71
72    // 解压缩方法
73    public static string Decompress(string compressedData, Node huffmanTree)
74    {
75        var decompressedData = new StringBuilder();
76        var currentNode = huffmanTree;
77        foreach (char bit in compressedData)
78        {
79            if (bit == '0')
80            {
81                currentNode = currentNode.Left ?? throw new ArgumentException("Invalid Huffman tree or data");
82            }
83            else if (bit == '1')
84            {
85                currentNode = currentNode.Right ?? throw new ArgumentException("Invalid Huffman tree or data");
86            }
87
88            if (currentNode.Left == null && currentNode.Right == null)
89            {
90                decompressedData.Append(currentNode.Value);
91                currentNode = huffmanTree;
92            }
93        }
94        return decompressedData.ToString();
95    }
96}
97
98// 需要自定义优先队列PriorityQueue,这里仅示意,你可以自己实现或使用.NET中的堆结构
99public class PriorityQueue<T> where T : IComparable<T>
100{
101    // ... 实现优先队列相关方法 ...
102}
103
104// 使用:
105var frequencies = new Dictionary<char, int>();
106// 假设已统计好字符串中各字符频率并填充到frequencies中
107var huffmanTree = HuffmanCoding.BuildHuffmanTree(frequencies);
108var huffmanCodes = HuffmanCoding.GenerateCodes(huffmanTree);
109var inputString = "Your input string";
110var compressed = HuffmanCoding.Compress(inputString, huffmanCodes);
111var decompressed = HuffmanCoding.Decompress(compressed, huffmanTree);

注意上述代码未包含优先队列PriorityQueue<T>的完整实现,您需要自行补充或使用现有的.NET库实现。在实际应用中,为了便于存储和传输,压缩后的比特流通常会转化为二进制或Base64格式。

目录
相关文章
|
2月前
|
开发者 C# Android开发
Xamarin 与 .NET:解锁现代化移动应用开发的超级武器——深入探讨C#与.NET框架如何赋能跨平台应用,实现高效编码与卓越性能
【8月更文挑战第31天】Xamarin 与 .NET 的结合为开发者提供了强大的平台,用于构建现代化移动应用。通过 C# 和 .NET 框架,Xamarin 可以实现一次编写、多平台运行,覆盖 iOS、Android 和 Windows。这种方式不仅节省了开发时间和成本,还保证了应用的一致性和高质量。Xamarin 是一个开源框架,专为跨平台移动应用开发设计,允许使用 C# 语言和 .NET 核心库构建原生应用,并访问各平台特定功能。微软维护的 Xamarin 是 Visual Studio 生态系统的一部分,极大地提高了开发效率。
72 0
|
5月前
|
C#
C# 获取文件编码格式
C# 获取文件编码格式
53 0
|
5月前
|
存储 算法 数据处理
C# | 上位机开发新手指南(十一)压缩算法
流式压缩 流式压缩是一种能够实时处理数据流的压缩方式,例如音频、视频等实时传输的数据。 通过流式压缩算法,我们可以边读取边压缩数据,并能够随时输出已压缩的数据,以确保数据的实时性和减少存储和传输所需的带宽。 块压缩 块压缩则是将数据划分为固定大小的块,在每个块内进行独立的压缩处理。块压缩通常适用于文件、存储、传输等离线数据处理场景。 字典压缩 字典压缩是一种基于字典的压缩算法,通过建立一个字典来存储一组重复出现的字符串,并将这些字符串替换成字典中相应的索引,从而减少数据的存储和传输。字典压缩算法可以更好地处理数据中的重复模式,因为它们可以通过建立字典来存储和恢复重复出现的字符串。
111 0
C# | 上位机开发新手指南(十一)压缩算法
|
5月前
|
XML 存储 JSON
C# 对象存储 (轻松实现序列化 | Xml | Json | 加密 | 压缩 | 注册表 | Redis)
开发时经常会遇到需要保存配置的情况,最常见的实现方式是将对象序列化成Json,再写入文件并保存到本地磁盘。 本文将使用开源库**ApeFree.DataStore**来替换原有的对象存储过程,实现一个可以随意切换存储方式的对象存储方法。 ApeFree.DataStore是一款可配置的对象存储库,支持在不同平台/介质中对内存中的对象进行存储与还原(如本地存储、注册表存储)。支持配置序列化格式(如Json、Xml),支持配置压缩算法(如GZip、Defalte),支持配置加密算法(如AES、RSA)。
116 0
C# 对象存储 (轻松实现序列化 | Xml | Json | 加密 | 压缩 | 注册表 | Redis)
C#使用base64对字符串进行编码和解码的测试
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
C#使用base64对字符串进行编码和解码的测试
推荐一个C#开发的、跨平台的解压缩的开源项目,值得收藏
一个纯C#压缩库,用于.NET Standard 2.0、2.1、.NET Core 3.1和.NET 5.0
155 0
推荐一个C#开发的、跨平台的解压缩的开源项目,值得收藏
|
JavaScript 前端开发 PHP
C#(五)之常量、@控制符、转译符、ASCII编码,Console.Write
对C#的常量,ASCII编码、@控制符、“+”连接符、Console.WriteLine及转译字符的简单应用。
317 0
C#(五)之常量、@控制符、转译符、ASCII编码,Console.Write
|
C# 数据安全/隐私保护
C# 压缩PDF图片
文档中包含图片的话,会使得整个文档比较大,占用存储空间且不利于快速、高效的传输文件。针对一些包含大量高质图片的PDF文档,若是对图片进行压缩,可以有效减少文档的占用空间。并且,在文档传输过程中也可以减少传送时间,提高效率。
1268 0
C#对byte数组压缩和解压
版权声明:欢迎评论和转载,转载请注明来源。 https://blog.csdn.net/zy332719794/article/details/28636469 直接上代码 ...
1742 0