哈夫曼树哈夫曼编码

作者:@kuaiquxie
作者的github:https://github.com/bitebita
本文为作者原创,如需转载,请注明出处:https://www.cnblogs.com/dzwj/p/15659493.html


哈夫曼树哈夫曼编码

 

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

输入格式:

第一行输入叶子结点个数,接着依次输入权值。

输出格式:

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

输入样例:

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

8
5 29 7 8 14 23 3 11
 
结尾无空行
 
代码如下:
复制代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int all_weight;
typedef struct
{
    int weight;
    int parent,lchird,rchild;
}HTNode,*HuffmanTree;
void InitHuffmanTree(HuffmanTree &H,int n)
{
    if(n<=1) return ;
    int m=2*n-1;
    H=new HTNode[m+1];
    for (int i = 1; i <= m; i++)
    {
        H[i].parent=0;
        H[i].lchird=0;
        H[i].rchild=0;
    }
    for (int i = 1; i <= n; i++)
    {
        cin>>H[i].weight;
    }
}

bool cmp(HTNode a,HTNode b)
{
    return a.weight<b.weight;
}
void Select(HuffmanTree H,int l,int &s1,int &s2)
{
    HuffmanTree M;
    M=new HTNode[l+1];
    for (int i = 1; i <= l; i++)
    {
        M[i].weight=H[i].weight;
        M[i].parent=H[i].parent;
        M[i].lchird=H[i].lchird;
        M[i].rchild=H[i].rchild;
    }
    sort(M+1,M+l+1,cmp);
    int a[2]={0};
    int num=0;
    for (int i = 1; i <= l; i++)
    {
        if(M[i].parent==0)
        {
            for (int j = 1; j <= l; j++)
            {
                if(M[i].weight==H[j].weight&&H[j].parent==0&&j!=a[0])
                {
                    a[num++]=j;
                    break;
                }
            }
        }
        if(num==2) break;
    }
    s1=a[0];
    s2=a[1];
    delete M;
}
typedef char** HuffmanCode;
void CreateHuffmanTree(HuffmanTree &H,int n)
{
    int m=2*n-1;
    int s1,s2;
    for (int i = n+1; i <= m; i++)
    {
        Select(H,i-1,s1,s2);
        H[s1].parent=i; H[s2].parent=i;
        H[i].lchird=s1; H[i].rchild=s2;
        H[i].weight=H[s1].weight+H[s2].weight;
        all_weight=all_weight+H[i].weight;
    }
}
void CreateHuffmanCode(HuffmanTree H,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;
        int f=H[i].parent;
        while (f!=0)
        {
            --start;
            if (H[f].lchird==c)
            {
                cd[start]='0';
            }
            else cd[start]='1';
            c=f;
            f=H[f].parent;
        }
        HC[i]=new char[n-start];
        strcpy(HC[i],&cd[start]);
    }
    delete cd;
}
int main()
{
    HuffmanTree H;
    HuffmanCode HC;
    int n;
    cin>>n;
    if(n==0||n==1||n==2){
        cout<<"error";
    return 0;
    }
    InitHuffmanTree(H,n);
    CreateHuffmanTree(H,n);
    CreateHuffmanCode(H,HC,n);
    for (int i = 1; i <= n; i++)
    {
        cout<<H[i].weight<<"编码为";
        cout<<HC[i]<<endl;
    }
    cout<<"WPL:"<<all_weight;
    return 0;
}
复制代码

 

 

posted @   kuaiquxie  阅读(132)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示