05-树9 Huffman Codes(30 point(s))

题目位置
哇撒 本来以为好难啊0 0 后来才发现 做法 题中都给出来了,简直狗血,,,,
分析:
首先0 0 什么样的是huffman tree
1.左右子树同时存在.
2.层数 越大,叶子结点的权值越大
3.不存在前缀编码
解决:
先构造一个正确的huffman tree ,然后计算出WPL.
以WPL为一个比对标准.
故评判一个huffman tree的方法就是:
WPL相等且同时不存在前缀编码.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct HuffmanTree *minDeep;
typedef struct HuffmanTree *position;
struct HuffmanTree{
    char Data[2];
    int Frequencies;
    position Left;
    position Right;
};
position Delete();
void countWPL(int *frequency);
void Insert(position T);
minDeep *deep;
int N;
int size;
int WPL=0;
int path=0;
int main(){
    int i,frequencies;
    char data[2];
    position T,T2,T3;
    scanf("%d",&N);
    int frequency[N];
    deep= (minDeep*)malloc(N*sizeof(minDeep));
    T = (position)malloc(sizeof(struct HuffmanTree));
    T->Frequencies=-1;
    deep[0]=T;
    size=0;
    for(i=0;i<N;i++){
        scanf("%s %d",&data,&frequencies);
        frequency[i]=frequencies;
    T = (position)malloc(sizeof(struct HuffmanTree));
    T->Data[0]=data[0];
    T->Frequencies=frequencies;
    T->Left=NULL;
    T->Right=NULL;
        Insert(T);
    }
    while((T=Delete())&&(T2=Delete())){
          T3=(position)malloc(sizeof(struct HuffmanTree));
          T3->Frequencies=T->Frequencies+T2->Frequencies;
          T3->Left=T;
          T3->Right=T2;
          T3->Data[0]='0';
          Insert(T3);
    }
    postTraversal(T);
    int people;
    scanf("%d",&people);
    for(i=0;i<people;i++){
    countWPL(frequency);
    if(i+1<people)printf("\n");
    }
}
void countWPL(int *frequency){
    int flag=0;
    char path[N][64];
    int i,j;
    char data[2];
    int WPL2=0;
    for(i=0;i<N;i++)
    {   scanf("%s",data);
        scanf("%s",path[i]);
        WPL2+=strlen(path[i])*frequency[i];
    }
    if(WPL2==WPL){
        for(i=0;i<N&&flag!=1;i++){
        for(j=i+1;j<N&&flag!=1;j++)
        {
            if(strlen(path[i])<strlen(path[j])){
                if(strncmp(path[i],path[j],strlen(path[i]))==0)flag=1;
            }else{
                if(strncmp(path[i],path[j],strlen(path[j]))==0)flag=1;
            }
        }
        }
        if(!flag)printf("Yes");
        else printf("No");
    }
    else printf("No");
}
void postTraversal(position T){
    if(T){
            path+=1;
            postTraversal(T->Left);
            path-=1;
            path+=1;
            postTraversal(T->Right);
            path-=1;
            if(!(T->Left&&T->Right))WPL+=T->Frequencies*path;
    }
    else return;
}
position Delete(){
if(!size)return NULL;
position T = deep[1];
int i=1;
deep[1]=deep[size];
for(;i*2<=size-1;){
    if(i*2+1<=size-1){
    if(deep[i*2]->Frequencies<deep[i*2+1]->Frequencies)
    {
        if(deep[i*2]->Frequencies>deep[size]->Frequencies)break;
        else deep[i]=deep[i*2],i*=2;
    }else{
        if(deep[i*2+1]->Frequencies>deep[size]->Frequencies)break;
        else deep[i]=deep[i*2+1],i=i*2+1;
    }
    }
    else{
        if(deep[i*2]->Frequencies<deep[size]->Frequencies)deep[i]=deep[i*2],i*=2;
        else break;
    }
}
    deep[i]=deep[size];
    size--;
    return T;
}
void Insert(position T){
    size++;
    int i=size;
    for(;deep[i/2]->Frequencies>T->Frequencies;i=i/2){
            deep[i]=deep[i/2];
    }
    deep[i]=T;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值