简单介绍
哈夫曼编码通过利用字符出现频率,将较常见的字符用较短的编码表示,从而实现数据的压缩和解压缩。
哈夫曼编码(Huffman Coding)是一种基于字符频率进行数据压缩的算法,由David A. Huffman于1952年提出。该算法利用字符出现的频率信息,将出现频率较高的字符用较短的编码表示,而出现频率较低的字符用较长的编码表示,从而有效地减小了数据的存储或传输大小。
哈夫曼编码的基本思想如下:
统计字符频率:遍历待压缩的数据,统计每个字符的出现频率。
构建哈夫曼树:根据字符频率,构建一个哈夫曼树。哈夫曼树是一种特殊的二叉树,其中频率较高的字符位于树的较低层,频率较低的字符位于树的较高层。
分配编码:从根节点开始,给哈夫曼树的左子树分配编码值"0",给右子树分配编码值"1"。通过遍历哈夫曼树的路径,可以得到每个字符的哈夫曼编码。
生成压缩数据:用字符的哈夫曼编码替换原始数据中的字符,从而生成压缩后的数据。
哈夫曼编码的特点是唯一可译性,即任何编码都不会是其他编码的前缀,保证了解码的准确性。
在解压缩时,使用相同的哈夫曼树,通过从根节点开始,根据编码值逐步遍历哈夫曼树,即可将压缩后的编码逐一映射为原始字符,从而还原原始数据。
代码示例
function huffmanEncode(text)
-- 统计字符频率
local frequency = {}
for i = 1, #text do
local char = text:sub(i, i)
frequency[char] = (frequency[char] or 0) + 1
end
-- 构建字符节点列表
local nodes = {}
for char, freq in pairs(frequency) do
table.insert(nodes, {char = char, freq = freq})
end
-- 构建哈夫曼树
while #nodes > 1 do
table.sort(nodes, function(a, b) return a.freq < b.freq end)
local left = table.remove(nodes, 1)
local right = table.remove(nodes, 1)
local parent = {left = left, right = right, freq = left.freq + right.freq}
table.insert(nodes, parent)
end
local root = nodes[1] -- 哈夫曼树的根节点
-- 构建编码表
local codeTable = {}
local function buildCode(node, code)
code = code or "" -- 初始化编码
if node.char then -- 叶子节点,记录编码
codeTable[node.char] = code
else -- 非叶子节点,递归构建编码
buildCode(node.left, code .. "0")
buildCode(node.right, code .. "1")
end
end
buildCode(root)
-- 编码文本
local encodedText = ""
for i = 1, #text do
local char = text:sub(i, i)
encodedText = encodedText .. codeTable[char]
end
return encodedText, codeTable
end
function huffmanDecode(encodedText, codeTable)
-- 构建解码表
local decodeTable = {}
for char, code in pairs(codeTable) do
decodeTable[code] = char
end
-- 解码文本
local decodedText = ""
local code = ""
for i = 1, #encodedText do
code = code .. encodedText:sub(i, i)
local char = decodeTable[code]
if char then
decodedText = decodedText .. char
code = ""
end
end
return decodedText
end
-- 示例使用
local originalText = "Hello, Huffman Encoding!"
print("原始文本:", originalText)
local encodedText, codeTable = huffmanEncode(originalText)
print("编码后:", encodedText)
local decodedText = huffmanDecode(encodedText, codeTable)
print("解码后:", decodedText)
示例中,首先统计文本中字符的频率,然后构建哈夫曼树,编码表和解码表。之后,用编码表来编码文本,或者用解码表来解码编码后的文本