4-5-2 哈夫曼树 哈夫曼编码 (30 分)

 

 题意:不能是前缀码而且是哈弗曼算法算出的最优编码长度的编码就行

基本思路:先根据所给字符和频率构造哈夫曼树,算出最优wpl编码数sum;后面每一套验证是否有前缀码和是否wpl=sum;

#include<stdio.h>
#include<malloc.h>
#include<map>
using namespace std;
typedef struct node {
    char le;
    int fre;
    struct node* left;
    struct node* right;
} *pnode;
int msize = 0, sum = 0,sum1=0, n;//msize为mdui的长度;
pnode root;
pnode crtree(pnode mroot,char k[],int n,int i);//验证代码时构造树来判断
int flag = 0;//树是否有前缀码的判断标志
pnode mdui[10000];
int judge(char m);//判断是否为所给字符;
void insert(pnode h);//插入堆函数
pnode sele();//删除堆函数
int  calculate(pnode h, int cnt, int l);//计算前缀码函数
map<char, int>t; //最简单的map应用,储存字符对应的频率
char lett[65];//储存给的字符
char code[65][65];//储存验证的编码
int main()
{
    mdui[0] =(pnode)malloc(sizeof(sizeof(struct node)));
   mdui[0]->fre = -1;;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        pnode dno=(pnode)malloc(sizeof(struct node));
        getchar();
        scanf("%c %d", &dno->le, &dno->fre);
        lett[i] = dno->le;
        t[dno->le] = dno->fre;
        dno->left = dno->right = NULL;
        insert(dno);
    }
    for (int i = 0; i < n - 1; i++) {
        pnode dno1 = sele(), dno2= sele();
        pnode dno3 = (pnode)malloc(sizeof(struct node));
        dno3->fre = dno1->fre + dno2->fre;
        dno3->left = dno1; dno3->right = dno2;
        dno3->le = '#';
        insert(dno3);
    }
  sum=calculate(mdui[1], -1,0);
  int m; scanf("%d", &m);
  while (m--) {
      flag = 0;
      pnode proot = NULL;
      for (int j = 0; j < n; j++) {
          getchar(); getchar(); getchar();
          scanf("%s", code[j]);
      }
      for (int i = 0; i < n; i++) {
          proot = crtree(proot,code[i], 0, i);
      }
      sum1 = calculate(proot, -1, 0);
      if (flag != 1) if (sum1 ==sum) printf("Yes"); else printf("No");
      else printf("No");
      if (m != 0) printf("\n");
   }
    return 0;
}
int judge(char m) {
    if (m<= '9' && m >= '0' || m <= 'z' && m >= 'a' || m >= 'A' && m <= 'Z'||m=='_') {
        return 1;
    }
    else return 0;
}
void insert(pnode  h) {
    int i = ++msize;
    mdui[i] = (pnode)malloc(sizeof(struct node));
    mdui[i]->left = mdui[i]->right = NULL;
    for (; mdui[i / 2]->fre > h->fre; i = i / 2) {
        mdui[i] = mdui[i / 2];
    }
    mdui[i] = h;
}
pnode sele() {
    struct node* root = (pnode)malloc(sizeof(struct node));
    root->left = root->right = NULL;
    root = mdui[1];
    pnode temp = mdui[msize--];
    int parent = 1,child;
    for (; parent * 2 <= msize; parent = child) {
        child = parent * 2;
        if (child + 1 < msize && mdui[child + 1]->fre < mdui[child]->fre) child++;
        if (temp->fre < mdui[child]->fre) break;
        else {
            mdui[parent] = mdui[child];
            parent = child;
        }
    }
    mdui[parent] = temp;
    return root;
}
int  calculate(pnode h, int cnt, int l) {
    cnt++; l = 0;
    if (judge(h->le) == 1) {
        l= t[h->le] * cnt;
    }
    if (h->left) l+=calculate(h->left, cnt,0);
    if (h->right) l+=calculate(h->right, cnt,0);
    return l;
}
pnode crtree(pnode mroot,char k[], int n,int i) {
    if (k[n] == '\0') {
        if (mroot != NULL) flag = 1;
        else {
            mroot = (pnode)malloc(sizeof(struct node));
            mroot->le = lett[i];
            mroot->fre = t[lett[i]];
            mroot->left = mroot->right = NULL;
        }
    }
    else {
        if (mroot == NULL) {
            mroot = (pnode)malloc(sizeof(struct node));
            mroot->le = '#';
            mroot->left = mroot->right = NULL;
        }
        if (k[n] == '0') mroot->left=crtree(mroot->left, k, n + 1, i);
        else mroot->right=crtree(mroot->right, k, n + 1, i);
    }
    return mroot;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值