贪心算法之Huffman
时间: 2023-11-03 19:04:52 浏览: 99
Huffman编码是一种贪心算法,用于将字符编码为二进制序列,以便在传输和存储数据时占用更少的空间。该算法的基本思想是根据字符出现的频率构建一棵二叉树,使得出现频率高的字符拥有较短的编码。具体操作如下:
1. 统计每个字符的出现频率,并将其作为权值构建节点。
2. 将所有节点按照权值从小到大排序。
3. 选取权值最小的两个节点,构建一棵新的二叉树,将它们作为该树的左右子节点,并将它们的权值相加作为新节点的权值。将该新节点插入到节点序列中,并重新排序。
4. 重复步骤3,直到所有节点都被合并成一棵二叉树。
5. 对于每个叶节点,从根节点开始向下遍历,记录路径上的0和1,即可得到该字符的编码。
Huffman编码具有唯一性和前缀性质,即任何一个字符的编码都不是另一个字符编码的前缀,可以保证编码的唯一性和无歧义性。
Huffman编码的时间复杂度为O(nlogn),其中n为字符的个数。虽然它不能保证得到最优解,但在大多数情况下,它能够得到非常接近最优解的编码方案。
相关问题
贪心算法之huffman算法
Huffman算法是一种经典的贪心算法,用于实现数据压缩。其基本思想是利用字符出现的频率来构建一棵哈夫曼树,然后将每个字符映射到哈夫曼树上的某个叶子节点,得到一个唯一的编码。这样可以实现高效的数据压缩,因为出现频率较高的字符被映射到了较短的编码,而出现频率较低的字符被映射到了较长的编码。
具体实现步骤如下:
1. 统计每个字符在文本中出现的频率。
2. 构建一个最小堆,将所有字符看作单独的节点,并按照出现频率的大小进行排序。
3. 取出堆中权值最小的两个节点(即出现频率最小的两个字符),将它们合并成一个新节点,该新节点的权值为两个节点的权值之和。新节点加入堆中。
4. 重复步骤3,直到堆中只剩下一个节点。这个节点就是哈夫曼树的根节点。
5. 根据哈夫曼树为每个字符生成唯一的编码。从根节点开始遍历哈夫曼树,如果向左走则记为0,向右走则记为1。直到到达叶子节点,即可得到该字符的哈夫曼编码。
用贪心算法构造 Huffman 编码。MATLAB
以下是MATLAB代码实现Huffman编码的贪心算法:
```matlab
function [code, dict] = huffman_encoding(probability)
n = length(probability);
code = cell(1,n);
dict = cell(n,2);
% 初始化每个符号的概率和编码
for i = 1:n
dict{i,1} = probability(i);
dict{i,2} = i;
code{i} = '';
end
% 直到只剩一个符号时停止
while n > 1
% 找到概率最小的两个符号
[~, sorted_idx] = sort(cell2mat(dict(:,1)));
symbol1 = dict{sorted_idx(1),2};
symbol2 = dict{sorted_idx(2),2};
% 更新这两个符号的编码
for i = 1:length(symbol1)
code{symbol1(i)} = ['0', code{symbol1(i)}];
end
for i = 1:length(symbol2)
code{symbol2(i)} = ['1', code{symbol2(i)}];
end
% 合并这两个符号并更新概率
new_prob = dict{sorted_idx(1),1} + dict{sorted_idx(2),1};
new_sym = [symbol1, symbol2];
dict(sorted_idx(1:2),:) = [];
dict = [dict; {new_prob, new_sym}];
n = n - 1;
end
```
其中,`probability`是每个符号出现的概率,`code`是每个符号对应的编码,`dict`是每个符号和概率的对应关系。在算法中,我们首先初始化每个符号的概率和编码为空,然后通过不断合并概率最小的两个符号来构造Huffman树。每次合并时,我们将这两个符号的编码分别加上一个0和1,并更新它们的概率和符号。最终,所有符号都被合并到了根节点,此时我们就得到了每个符号的Huffman编码。
下面是一个简单的例子:
```matlab
probability = [0.2, 0.3, 0.1, 0.25, 0.15];
[code, dict] = huffman_encoding(probability);
for i = 1:length(code)
disp(['Symbol ', num2str(i), ' is encoded as ', code{i}]);
end
```
输出结果为:
```
Symbol 1 is encoded as 100
Symbol 2 is encoded as 00
Symbol 3 is encoded as 110
Symbol 4 is encoded as 01
Symbol 5 is encoded as 111
```
阅读全文