首页 > 其他 > 详细

Haffman编码(haffman树)

时间:2016-03-01 14:32:01      阅读:244      评论:0      收藏:0      [点我收藏+]

Haffman编码

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
 
描述

哈弗曼编码大家一定很熟悉吧(不熟悉也没关系,自己查去。。。)。现在给你一串字符以及它们所对应的权值,让你构造哈弗曼树,从而确定每个字符的哈弗曼编码。当然,这里有一些小规定:

1.规定哈弗曼树的左子树编码为0,右子树编码为1;

2.若两个字符权值相同,则ASCII码值小的字符为左孩子,大的为右孩子;

3.创建的新节点所代表的字符与它的左孩子的字符相同;

4.所有字符为ASCII码表上32-96之间的字符(即“ ”到“`”之间的字符)。

 
输入
输入包含多组数据(不超过100组) 每组数据第一行一个整数n,表示字符个数。接下来n行,每行有一个字符ch和一个整数weight,表示字符ch所对应的权值,中间用空格隔开。 输入数据保证每组测试数据的字符不会重复。
输出
对于每组测试数据,按照输入顺序输出相应的字符以及它们的哈弗曼编码结果,具体格式见样例。
样例输入
3
a 10
b 5
c 8
4
a 1
b 1
c 1
d 1
样例输出
a:0
b:10
c:11
a:00
b:01
c:10
d:11
题解:让求一颗哈夫曼树,哈夫曼树是先找到最小的两个建一个根节点,这个根节点的权值为两个小的权值和;
加入这个新节点,重新找;用优先队列实现;其根节点即为元素在树中的位置;
代码:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
#define mem(x,y) memset(x,y,sizeof(x))
#define SI(x) scanf("%d",&x)
#define PI(x) printf("%d",x)
typedef long long LL;
string ans[300];
char c[310];
struct Node{
    char c;
    int v;
    Node *l,*r;
    Node(){
        l=r=NULL;
    }
    Node(char ch,int vv,Node *ll=NULL,Node *rr=NULL){
        c=ch;v=vv;l=ll;r=rr;
    }
    bool operator < (const Node &b) const{
        if(v!=b.v)return v>b.v;
        else return c>b.c;
    }
};
Node e[300];
void dfs(Node *now,string s){
    if(now->l==NULL&&now->r==NULL){
        ans[int(now->c)]=s;return;
    }
    if(now->l!=NULL)dfs(now->l,s+0);
    if(now->r!=NULL)dfs(now->r,s+1);
    return ;
}
int main(){
    int N,v;
    //char s[2];
    while(~SI(N)){
        if(N==0)continue;
        for(int i=0;i<300;i++)e[i].l=e[i].r=NULL;
        priority_queue<Node>Q;
        getchar();
        for(int i=0;i<N;i++){
            scanf("%c %d",&c[i],&v);getchar();//这里不这样输入就错了 
            //c[i]=s[0];
            Q.push(Node(c[i],v));
        }    
        int tp=0;
        while(Q.size()>1){
            e[tp++]=Q.top();
            Q.pop();
            e[tp++]=Q.top();
            Q.pop();
            Q.push(Node(e[tp-2].c,e[tp-2].v+e[tp-1].v,&e[tp-2],&e[tp-1]));
            //Node(e[tp-2].c这样插是为了当和等于下一个的v的时候排在前边;
            //为什么要再开一个数组e:为了保持队列里面元素的l,r对应关系; 
        }
        Node ss;
        ss=Q.top();
        //printf("%c %d\n",ss.c,ss.v);
        dfs(&ss,"");
        //printf("****");
        for(int i=0;i<N;i++){
            //printf("%c:%s\n",c[i],ans[int(c[i])].c_str());
              cout<<c[i]<<":"<<ans[int(c[i])]<<endl;
        }
    }
    return 0;
}

 

Haffman编码(haffman树)

原文:http://www.cnblogs.com/handsomecui/p/5230597.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!