• 贪心算法-Huffman算法



    源代码

    #include <stdlib.h>

    #include

    #include

    #include

    struct HtNode{

    double weight;

    int parent,lchild,rchild;

    };

    struct HtTree{

    HtNode* ht;

    int root;

    };

    typedef struct HtTree* PHtTree;

    //构造有n个节点的哈夫曼树

    PHtTree Huffman (int n,int* w)

    {

    PHtTree pht;

    HtNode* ht;

    //用于记录权值最小的两棵树在数组中的位置

    int i,j,p1,p2;

    //min1,min2用于记录两个最小的权值

    double min1,min2;

    //输入合法

    if(n<=0) return 0;

    //动态分配Haffman树的空间

    //int*n=(int*)malloc(sizeof(int)*n);

    pht=(HtTree*)malloc(sizeof(HtTree));

    pht->ht=(HtNode*)malloc(sizeof(HtNode)*(2*n-1));

    //n个叶子共有2*n-1个节点

    //初始化,设置ht数组的初始值

    for(i=0;i<2*n-1;i++)

    {

    pht->ht[i].parent=0;

    if(i

    {

    pht->ht[i].weight=w[i];

    }

    else

    {

    pht->ht[i].weight=1000;

    }

    }

    //执行n-1次合并操作,即构造哈夫曼树的n-1个内部节点

    for(i=0;i

    {

    p1=p2=0;

    //相关变量赋初值

    min1=min2=1000;//相当于一个大数

    for(j=0;j

    {

    if(pht->ht[j].parent==0)

    {

    if(pht->ht[j].weight

    min1=pht->ht[j].weight;

    p1=j;

    }

    }

    }

    for(j=0;j

    {

    if(pht->ht[j].parent==0)

    {

    if((pht->ht[j].weight>min1)&&(pht->ht[j].weight<=min2)&&(j!=p1))

    {

    min2=pht->ht[j].weight;

    p2=j;

    }

    }

    }

    pht->ht[p1].parent=n+i;

    pht->ht[p2].parent=n+i;

    pht->ht[n+i].weight=min1+min2;

    pht->ht[n+i].lchild=p1;

    pht->ht[n+i].rchild=p2;

    }

    //返回树

    return pht;

    }

    //计算Huffman编码

    void HuffmanCode(char** HC,int n,PHtTree pht)

    {

    int flag;

    //每个字符的编码最大长度不会超过n

    //这跟树的深度有关

    char*c;

    //c=(char*)malloc(sizeof(char)*n);

    //分配n个字符指针数组空间

    //第n-1单元存储编码串的结束符

    int start;

    //逐个对n个字符求其哈夫曼编码

    for(int i=0;i

    {

    flag=0;

    //start=n-1;

    //k,f是两个工作指针,f指向k的父亲

    for(int k=i,f=pht->ht[i].parent;f!=0;k=f,f=pht->ht[k].parent)

    {

    flag++;

    //左边分配0,右边分配1

    }

    //---------------

    c=(char*)malloc(sizeof(char)*(flag));

    c[flag]='\0';

    for(int k=i,f=pht->ht[i].parent;f!=0;k=f,f=pht->ht[k].parent)

    {

    if(pht->ht[f].lchild==k)

    {

    c[--flag]='0';

    }

    else

    {

    c[--flag]='1';

    }

    }

    //为第i个字符编码分配空间

    //因为路径有长有短

    HC[i]=(char*)malloc(sizeof(char));

    strcpy(HC[i],c);

    }

    }

    int main()

    {

    //输入

    int n;

    int m;

    HtNode* ht;

    int* weight;

    char** HC;

    PHtTree pht;

    printf("请输入需要哈夫曼编码的节点数目\n");

    scanf("%d",&n);

    //分配内存空间

    ht=(HtNode*)malloc(sizeof(HtNode)*n);

    weight=(int*)malloc(sizeof(int)*n);

    HC=(char**) malloc(sizeof(char*)*n);

    printf("请输入各节点的值\n");

    for(int i=0;i

    {

    printf("第%d个节点的权值:\n",i);

    scanf("%d",&m);

    weight[i]=m;

    printf("\n");

    }

    //构造具有n个节点的Haffman树

    pht=Huffman(n,weight);

    HuffmanCode(HC,n,pht);

    //输出编码

    for(int i=0;i

    {

    int j=0;

    printf("第%d个字符的编码,它的权值为是%d:\n",i,weight[i]);

    {

    printf("%s\n",HC[i]);

    //j++;

    }

    }

    return 0;

    }

  • 相关阅读:
    python教程:*的用法,你可能错过了......
    linux安装MySQL8.0,密码修改权限配置等常规操作详解
    基于Springboot实现商品进销存管理系统
    Ansible-playbook的优化
    [笔记] Windows内核课程:保护模式《二》段寄存器介绍
    UE4 C++:事件绑定(输入、碰撞检测、定时器)
    Go学习第十二章——Go反射与TCP编程
    Echarts 折线图的详细配置过程
    Mac电脑音视频播放器: Infuse for Mac中文
    exFAT文件系统的目录与文件存储
  • 原文地址:https://blog.csdn.net/m0_62089210/article/details/127903661