哈夫曼树的建立以及哈夫曼编码

//主要源代码如下

#include<stdio.h>
#include<malloc.h>
#define MAX_NUM 105
typedef struct {
    int weight;
    char ch;
    int parent,lchild,rchild;
    int visited;
}HTnode,*HTree;
void selectTwoMin(HTree &HT,int n,int &s1,int &s2){
    int firMin=101,secMin=101;
    for(int i=1;i<=n;i++)
    if(!HT[i].visited&&HT[i].weight<=firMin){
        firMin=HT[i].weight;//在没有被访问的结点中选择出最小的频率
        s1=i;
    }
    HT[s1].visited=1;//将最小的频率对应的结点标记为已被访问
    for(int i=1;i<=n;i++)//继续在没有被访问的结点中选择出次小的频率
    if(!HT[i].visited&&HT[i].weight<=secMin){
        secMin=HT[i].weight;
        s2=i;
    }
    HT[s2].visited=1;//将次小的频率对应的结点标记为已被访问
}
int count;//全局变量,要进行编码的字符的个数。
void creatHuffmanTree(HTree &HT){
    int m,w,s1,s2;char ch;
    printf("请输入要进行编码的字符个数:");
    scanf("%d",&count);
    getchar();//吸收回车符号
    printf("请输入%d个字符对应的频率(%%),如:a 30\n",count);
    m=2*count-1;//哈夫曼树总结点个数
    HT=(HTree)malloc((m+1)*sizeof(HTnode));//创建需要的所有节点
    for(int i=1;i<=count;i++){//对count个叶子结点输入字母和对应的频率
        scanf("%c%d%*c",&ch,&w);//%*c用于吸收回车字符
        HT[i].ch=ch;
        HT[i].weight=w;
        HT[i].visited=0;//初始都标记没有被访问过
    }
    for(int i=count+1;i<=m;i++){//对剩下的非叶子结点进行初始化
        HT[i].ch='0';
        HT[i].lchild=HT[i].rchild=HT[i].parent=HT[i].weight=HT[i].visited=0;
    }
    for(int i=count+1;i<=m;i++){    //创建哈夫曼树
        selectTwoMin(HT,i-1,s1,s2);//得到最小频率下标s1,次小频率下标s2
        HT[s1].parent=i;//第i个结点为s1和s2对应结点的父母
        HT[s2].parent=i;
        HT[i].lchild=s1;//第i个结点的左右孩子分别为s1和s2对应的结点
        HT[i].rchild=s2;
        HT[i].weight=HT[s1].weight+HT[s2].weight;//更新第i个结点的频率
    }
}
void huffmanCoded(HTree &HT){   //哈夫曼编码
    char HC[MAX_NUM];
    int j;
    for(int i=1;i<=count;i++){//遍历1到count个的叶子结点,输出其哈夫曼编码
        j=0;//用于在HC数组中存编码的指针
        printf("字母%c的哈夫曼编码为:",HT[i].ch);
        //初始条件:当前结点为第i个叶子结点,当前父母为第i个叶子结点的父母
        //循环条件:parent!=0,即走到根结点结束编码
        //控制条件:将当前结点的父母为下次循环的当前结点,将当前父母的父母为下次循环的父母
        for(int cur=i,parent=HT[i].parent;parent!=0;cur=parent,parent=HT[parent].parent)
            if(HT[parent].lchild==cur) HC[j++]='0';//左孩为0
            else HC[j++]='1';                      //右孩为1
        for(int k=j-1;k>=0;k--) //逆序输出得到哈夫曼编码
        printf("%c",HC[k]);
        printf("\n");
    }
}
int main(){
    HTree HT;
    creatHuffmanTree(HT);
    huffmanCoded(HT);
    return 0;
}
/*
m 13
n 44
o 12
p 17
q 9
r 5
*/



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值