算法笔记贪心算法哈夫曼编码问题Word文件下载.docx
《算法笔记贪心算法哈夫曼编码问题Word文件下载.docx》由会员分享,可在线阅读,更多相关《算法笔记贪心算法哈夫曼编码问题Word文件下载.docx(16页珍藏版)》请在冰豆网上搜索。
![算法笔记贪心算法哈夫曼编码问题Word文件下载.docx](https://file1.bdocx.com/fileroot1/2022-10/9/0102ac0c-d6cb-439b-81f6-a78ae108d81a/0102ac0c-d6cb-439b-81f6-a78ae108d81a1.gif)
在一般情况下,若C是编码字符集,表示其最优前缀码的二叉树中恰有|C|个叶子。
每个叶子对应于字符集中的一个字符,该二叉树有|C|-1个内部节点。
给定编码字符集C及频率分布f,即C中任一字符c以频率f(c)在数据文件中出现。
C的一个前缀码编码方案对应于一棵二叉树T。
字符c在树T中的深度记为dT(c)。
dT(c)也是字符c的前缀码长。
则平均码长定义为:
使平均码长达到最小的前缀码编码方案称为C的最优前缀码。
2、构造哈弗曼编码
哈夫曼提出构造最优前缀码的贪心算法,由此产生的编码方案称为哈夫曼编码。
其构造步骤如下:
(1)哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T。
(2)算法以|C|个叶结点开始,执行|C|-1次的“合并”运算后产生最终所要求的树T。
(3)假设编码字符集中每一字符c的频率是f(c)。
以f为键值的优先队列Q用在贪心选择时有效地确定算法当前要合并的2棵具有最小频率的树。
一旦2棵具有最小频率的树合并后,产生一棵新的树,其频率为合并的2棵树的频率之和,并将新树插入优先队列Q。
经过n-1次的合并后,优先队列中只剩下一棵树,即所要求的树T。
构造过程如图所示:
具体代码实现如下:
(1)4d4.cpp,程序主文件
[cpp]
viewplain
copy
1.//4d4
贪心算法
哈夫曼算法
2.#include
"
stdafx.h"
3.#include
BinaryTree.h"
4.#include
MinHeap.h"
5.#include
<
iostream>
6.using
namespace
std;
7.
8.const
int
N
=
6;
9.
10.template<
class
Type>
Huffman;
11.
12.template<
13.BinaryTree<
int>
HuffmanTree(Type
f[],int
n);
14.
15.template<
16.class
Huffman
17.{
18.
friend
BinaryTree<
HuffmanTree(Type[],int);
19.
public:
20.
operator
Type()
const
21.
{
22.
return
weight;
23.
}
24.
//private:
25.
tree;
26.
Type
27.};
28.
29.int
main()
30.{
31.
char
c[]
{'
0'
'
a'
b'
c'
d'
e'
f'
};
32.
f[]
{0,45,13,12,16,9,5};
//下标从1开始
33.
t
HuffmanTree(f,N);
34.
35.
cout<
各字符出现的对应频率分别为:
endl;
36.
for(int
i=1;
i<
=N;
i++)
37.
38.
c[i]<
:
f[i]<
;
39.
40.
41.
42.
生成二叉树的前序遍历结果为:
43.
t.Pre_Order();
44.
45.
46.
生成二叉树的中序遍历结果为:
47.
t.In_Order();
48.
49.
50.
t.DestroyTree();
51.
0;
52.}
53.
54.template<
55.BinaryTree<
n)
56.{
57.
//生成单节点树
58.
Huffman<
*w
new
[n+1];
59.
z,zero;
60.
61.
=n;
62.
63.
z.MakeTree(i,zero,zero);
64.
w[i].weight
f[i];
65.
w[i].tree
z;
66.
67.
68.
//建优先队列
69.
MinHeap<
>
Q(n);
70.
Q.Insert(w[i]);
71.
72.
//反复合并最小频率树
73.
x,y;
74.
n;
75.
76.
x
Q.RemoveMin();
77.
y
78.
z.MakeTree(0,x.tree,y.tree);
79.
x.weight
+=
y.weight;
80.
x.tree
81.
Q.Insert(x);
82.
83.
84.
85.
86.
delete[]
w;
87.
88.
x.tree;
89.}
(2)BinaryTree.h二叉树实现
1.#include<
2.using
3.
4.template<
T>
5.struct
BTNode
6.{
T
data;
8.
BTNode<
*lChild,*rChild;
10.
BTNode()
12.
lChild=rChild=NULL;
13.
15.
BTNode(const
&
val,BTNode<
*Childl=NULL,BTNode<
*Childr=NULL)
16.
17.
data=val;
lChild=Childl;
rChild=Childr;
*
CopyTree()
*nl,*nr,*nn;
if(&
data==NULL)
27.
NULL;
29.
nl=lChild->
CopyTree();
30.
nr=rChild->
nn=new
(data,nl,nr);
nn;
35.};
38.template<
39.class
BinaryTree
40.{
*root;
BinaryTree();
~BinaryTree();
void
Pre_Order();
In_Order();
Post_Order();
TreeHeight()const;
TreeNodeCount()const;
52.
DestroyTree();
54.
MakeTree(T
pData,BinaryTree<
leftTree,BinaryTree<
rightTree);
55.
Change(BTNode<
*r);
56.
private:
void