数据结构实验6

7-1 哈夫曼树哈夫曼编码
输入一组整型权值,构建哈夫曼树,实现哈夫曼编码,并输出带权路径长度。

输入格式:
第一行输入叶子结点个数,接着依次输入权值。若叶子数为0或1,则输出error

输出格式:
输出哈夫曼编码,输出带权路径长度。

输入样例:
在这里给出一组输入。例如:

8
5 29 7 8 14 23 3 11
输出样例:
在这里给出相应的输出。例如:

5编码为0001
29编码为10
7编码为1110
8编码为1111
14编码为110
23编码为01
3编码为0000
11编码为001
WPL:271

代码:

#include<iostream>
#include<cstring>
using namespace std;
typedef char ** HuffmanCode;
typedef struct{
    int weight;
    int lchild,rchild,parent;
}HTNode,*HuffmanTree;

void min(HuffmanTree HT,int pos,int& s1,int& s2){
    s1=s2=-1;
    for(int i=1;i<pos;i++){
        if(HT[i].parent==0){
            if(s1==-1||HT[i].weight<HT[s1].weight){
                s2=s1;
                s1=i;
            }else if(s2==-1||HT[i].weight<HT[s2].weight){
                s2=i;
            }
        }
    }
}

void CreatHT(HuffmanTree& HT,int n){
    if(n<=1)return;
    int m=2*n-1;
    HT=new HTNode[m+1];
    for(int i=1;i<=m;++i){
        HT[i].weight=0;HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;
    }
    for(int i=1;i<=n;i++){
        cin>>HT[i].weight;
    }
    for(int i=n+1;i<=m;i++){
        int s1,s2;
        min(HT,i,s1,s2);
        HT[s1].parent=i;HT[s2].parent=i;
        HT[i].lchild=s1;HT[i].rchild=s2;
        HT[i].weight=HT[s1].weight+HT[s2].weight;
    }
}

void CreatHC(HuffmanTree HT,HuffmanCode& HC,int n){
    HC=new char*[n+1];
    char* cd=new char[n];
    cd[n-1]='\0';

    for(int i=1;i<=n;i++){
        int start=n-1;
        int c=i,f=HT[i].parent;
        while(f!=0){
            if(c==HT[f].lchild) cd[--start]='0';
            else cd[--start]='1';
            c=f;f=HT[c].parent;
        }
        HC[i]=new char[n-start];
        strcpy(HC[i],&cd[start]);
    }
    delete[] cd;
}

int main(){
    HuffmanTree HT;
    HuffmanCode HC;
    int n,WPL=0,j;
    cin>>n;
    if(n>1){
        CreatHT(HT,n);
        CreatHC(HT,HC,n);

        for(int i=1;i<=n;i++){
            cout<<HT[i].weight<<"编码为";
            for(j=0;HC[i][j]!='\0';j++){
                cout<<HC[i][j];
            }
            WPL+=j*HT[i].weight;
            cout<<endl;
        }
        cout<<"WPL:"<<WPL;
    }else{
        cout<<"error:输入的字符数必须大于1"<<endl;
    }
    return 0;
}
posted @   呓语-MSHK  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示