OJ 赫夫曼编码

描述

先从键盘输入若干电文所用符号及其出现的频率,然后构造赫夫曼树,从而输出赫夫曼编码。

注意:为了保证得到唯一的赫夫曼树,这里规定在构造赫夫曼树时,左孩子结点权值不大于右孩子结点权值,如若有多种选择,则尽量先选序号偏小的结点。编码时,左分支取“0”,右分支取“1

输入3行
第1行:符号个数n(2~20);
第2行:符号,用空格分隔;
第3行:各符号出现频率(用乘以100后的整数),用空格分隔;输出各符号对应的赫夫曼编码。一个符号一行,注意顺序。
例如:
a:10
b:110样例输入
5
a b c d e
40 20 15 10 15
样例输出
a:0
b:111
c:101
d:100
e:110
#include <iostream>
#include "cstring"
#include <stdio.h>
#include "iomanip"
#include "vector"
#include "cmath"
#include "stack"
#include "algorithm"
#include <math.h>
#include "map"
#include "queue"
#include "set"
using namespace std;
int p[1111];
int lon;
struct node
{


    char name;
    int w;
    node *l,*r;
};
bool operator <(node   a,node  b)
{
    return a.w>=b.w;
}
bool dfs(node * r,char s)
{
    if(r->name==s)
        return true;


    if(r->l)
    {
        p[lon++]=0;
        if(dfs(r->l,s))
            return true;
        lon--;
    }
    if(r->r)
    {
        p[lon++]=1;
        if(dfs(r->r,s))
            return true;
        lon--;
    }
    return false;
}
int main()
{
    freopen("a.txt","r",stdin);
    int n;
    cin>>n;
    char str[111111];
    int wei[11111];
    for(int i=0;i<n;i++)
    {
        cin>>str[i];
    }
    for(int i=0;i<n;i++)
    {
        cin>>wei[i];
    }
    priority_queue<node > q;
    node * t;
    for(int i=0;i<n;i++)
    {
        node t;
        t.l=NULL;
        t.r=NULL;
        t.name=str[i];
        t.w=wei[i];
        q.push(t);
    }
    node *a,*b;
    while(q.size()>=2)
    {
        node f=q.top();
        q.pop();
        a=new node;//之所以要用指针是因为,动态生成 的指针地址是动态的,如果是node 类型 地址是固定的
        a->name=f.name;
        a->l=f.l;
        a->r=f.r;
        a->w=f.w;
        node s=q.top();
        q.pop();
        b=new node;
        b->name=s.name;
        b->l=s.l;
        b->r=s.r;
        b->w=s.w;
        t=new node;
        t->name='*';
        t->w=a->w+b->w;
        t->l=a;
        t->r=b;
        q.push(*t);
    }
      node h=q.top();
      node *start=&h;
      for(int i=0;i<n;i++)
      {
          lon=0;
          dfs(start,str[i]);
          cout<<str[i]<<":";
          for(int j=0;j<lon;j++)
          {
              cout<<p[j];
          }
          cout<<endl;
      }


    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值