哈弗曼编码

来源:互联网 发布:实木床品牌 知乎 编辑:程序博客网 时间:2024/05/18 00:54

哈弗曼编码


问题描述:给定字符集C和每个字符的频率,求关于C的一个最优前缀码。

算法分析:构造最优前缀码的贪心算法就是哈夫曼算法(Huffman)

二元前缀编码存储:二叉树结构,每个字符作为树叶,对应这个字符的前缀码看作根到这片树叶的一条路径,每个结点通向左二子的边记作0,通向右儿子的边记作1.

算法复杂度分析:O(nlogn)

样例:
输入:
3
qwe
3 5 5

输出:
10110

以下是代码:

////  算法作业-哈弗曼编码.cpp//  LOY////  Created by pro on 16/5/24.//  Copyright (c) 2016年 loy. All rights reserved.//#include <stdio.h>#include <iostream>#include <string>#include <queue>using namespace std;struct node{    int f;   //频率    int pos;   //记录是第几个字母    int no;  //记录该节点编号    int l,r;  //记录左右结点的no    friend bool operator> (const node a, const node b)    {        return a.f > b.f;    }};node tree[1005];  //存储节点priority_queue<node, vector<node>, greater<node> >q;node init(int f,int pos,int no,int l,int r){    node tmp;    tmp.f = f; tmp.pos = pos; tmp.no = no; tmp.l = l; tmp.r = r;    return tmp;}string ans[1005];  //记录答案void solve(string s,node head){    if (head.l == 0 && head.r == 0)  //访问到叶子节点    {        ans[head.pos] = s;        return;    }    if (head.l != 0)  //存在左结点    {        solve(s + "0",tree[head.l]);    }    if (head.r != 0)  //存在右节点    {        solve(s + "1",tree[head.r]);    }}int main(){    int n;    cin >> n;    string s;    cin >> s;   //输入字符串    for (int i = 0; i < n; i++)    {        int num;        cin >> num;  //输入每个字母的频率        node tmp = init(num,i,i + 1,0,0);  //创建叶子节点        tree[i + 1] = tmp;        q.push(tmp);    }    int cnt = n + 1;    for (int i = 0; i < n - 1; i++)    {        node a = q.top(); q.pop();        node b = q.top(); q.pop();        node c =  init(a.f + b.f,0,cnt++,a.no,b.no);  //左子树为a,右子树为b        tree[cnt - 1] = c; //存储每个结点        q.push(c);    }    node head = q.top();    solve("",head);  //递归得出答案    for (int i = 0; i < n; i++)    {        cout << ans[i];    }    cout << endl;    return 0;}
0 0
原创粉丝点击