Skip to content

Commit a8f64f1

Browse files
authored
Create huffman
1 parent dc339d4 commit a8f64f1

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

huffman

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
Sample - Greediness
2+
贪心典型题(1)- 哈夫曼编码
3+
题目描述
4+
“霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩的熵编码(权编码)算法。也称“哈夫曼编码”,。
5+
1952年,David A. Huffman在麻省理工攻读博士时所发明的,并发表于《一种构建极小多余编码的方法》(A Method for the Construction of Minimum-Redundancy Codes)一文。
6+
在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,
7+
出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。
8+
例如,在英文中,e的出现机率最高,而z的出现概率则最低。当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26)。
9+
用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个比特。二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。
10+
倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。
11+
霍夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,
12+
叶结点到根结点的路径长度为叶结点的层数)。树的路径长度是从树根到每一结点的路径长度之和,记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),
13+
N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明霍夫曼树的WPL是最小的。” – 以上摘自维基百科
14+
现在问题来了:给出编码中每个字符出现的频率,求其WPL最小是多少。
15+
输入格式
16+
多组样例,以EOF结尾,对于每组样例:
17+
第一行: 一个正整数N(<=50000)代表编码数量。
18+
第二行: N个正整数(<=20000),代表每个编码的权重。
19+
输出格式
20+
对于每组样例,输出其最小的WPL,每个样例一行。
21+
样例输入
22+
23+
3
24+
8 5 8
25+
26+
样例输出
27+
28+
34
29+
Hint
30+
这颗树是这样的:根连接1号节点和权重8的编码。1号节点连接权重5的编码和另一个权重8的编码。
31+
下载资料:
32+
输入文件
33+
输出文件
34+
参考答案
35+
/***************************************************************************
36+
版权申明:本程序为北京交通大学《算法设计与分析》课程以及教材《算法设计与问题
37+
求解-编程实践》的教辅材料,著作权为北京交通大学计算机与信息技术学院视觉智能
38+
实验室李清勇教授所有,禁止用于任何盈利性质的商业行为。未经著作权所有人允许,
39+
禁止进行传播和出版。
40+
*************************************************************************/
41+
42+
/**************************************************************************
43+
解题思路:频率低的字符分配长的编码,否则分配短的编码。
44+
45+
**************************************************************************/
46+
/*code*/
47+
48+
#include <iostream>
49+
#include <bits/stdc++.h>
50+
using namespace std;
51+
const int N = 1e5+233;
52+
int n,a[N];
53+
long long ret;
54+
int main()
55+
{
56+
while(scanf("%d",&n)!=EOF)
57+
{
58+
priority_queue<int,vector<int>,greater<int> >que;
59+
for(int i=1; i<=n; ++i)
60+
{
61+
cin>>a[i];
62+
que.push(a[i]);
63+
}
64+
ret=0;
65+
while(1)
66+
{
67+
int first_val=que.top();que.pop(); //cout<<"first_val= "<<first_val<<endl;
68+
if(que.empty())break;
69+
int second_val=que.top();que.pop(); //cout<<"second_val= "<<second_val<<endl;
70+
int sum_val=first_val+second_val; //cout<<"sum_val= "<<sum_val<<endl;
71+
ret+=sum_val;
72+
que.push(sum_val);
73+
}
74+
cout<<ret<<endl;
75+
}
76+
return 0;
77+
}

0 commit comments

Comments
 (0)