6月11日数据结构——Huffman树

 

#include<stdio.h>
#include<stdlib.h>
#define leafNumber 20      //默认权值集合大小 
#define totalNumber 39     //数结点个数=2*leafNumber-1 
typedef struct {
    char data;                   //结点的值 
    int weight;                  //结点的权 
    int Parent,lchild,rchild;    //双亲、左、右子女结点指针 
}HTNode;
typedef struct {
    char elem[totalNumber];     //Huffman树存储数组
    int num;                //num是外结点数,root是根 
}HFTree;

//算法
void createHFTree (HTNode HT[],HFTree HElem[],char value[],int fr[],int n){
    //输入数据value[n]和相应权值fr[n],构造用三叉链表表示的Huffman树HT
    for(int i = 0;i<n;i++){
        HT[i].data = value[i];
        HElem[i].elem[i] = fr[i];
    }
    int i,k,s1,s2;
    int min1,min2;
    for(i = 0;i<leafNumber;i++)                //所有指针置空 
        HT[i].Parent = HT[i].lchild = HT[i].rchild = -1;
    for(i = n;i<2*n-1;i++){                //逐步构造Huffman树 
        min1 = min2 = 0x7fff;                    //min1是最小值,min2是次小值 
        s1 = s2 = 0;                       //s1是最小值点,s2是次小值点
        for(k = 0;k<i;k++)                 //构造Huffman树的过程 
            if(HT[k].Parent == -1)        //未成为其他树的子树 
                if(HT[k].weight<min1){     //新的最小值 
                    min2 = min1;
                    s2 = s1;                  //原来的最小值变成次小值 
                    min1 = HT[k].weight;    //记忆新的最小值 
                    s1 = k; 
                }else if(HT[k].weight<min2){   //新的次小值 
                    min2 = HT[k].weight;
                    s2 = k;
                }
            HT[s1].Parent=HT[s2].Parent=i;  //构造子树 
            HT[i].lchild=s1;
            HT[i].rchild=s2;
            HT[i].weight=HT[s1].weight+HT[s2].weight;
    }
} 

//建立Huffman编码
void createMessage(HTNode HT[],HFTree HElem[],int n){
    HFTree d;
    int i,c,f;
    for(i=0;i<n;i++)
    {
        d.num=n;
        c=i;
        f=HT[i].Parent;
        while(f!=0)
        {
            if(HT[f].lchild==c)
            d.elem[--d.num]='0';
            else
            d.elem[--d.num]='1';
            c=f;
            f=HT[f].Parent;
        }
        HElem[i]=d;
    }
} 

//输出Huffman编码
void printMessage (HTNode HT[],HFTree HElem[],int n) {
    printf("输出huffman编码:\n");
    for(int i=0;i<n;i++)
    {
        printf("%c\n",HT[i].data);
        for(int k=HElem[i].num;k<n;k++)
        printf("%c",HElem[i].elem[k]);
        printf("\n\n");
    }
}

main(){
    HTNode HT[2*leafNumber];
    HFTree HElem[leafNumber],d;
    int n,b[n];     //所需要的数据个数
    printf("请输入需要编码的元素个数(1->%d):",leafNumber);
    scanf("%d",&n); 
    if(n>leafNumber||n<1)
        return 1;
    char a[n];
    for(int i = 0;i<n;i++){
        fflush(stdin);
        printf("\n请输入第%d位的结点值:",i+1);
        scanf("%c",&a[i]);
        printf("\n请输入第%d位权值:",i+1);
        scanf("%d",&b[i]);
    }    
    createHFTree(HT,HElem,a,b,n);    
    createMessage(HT,HElem,n);
    printMessage(HT,HElem,n);
} 

 

转载于:https://www.cnblogs.com/lvzhiqi/p/11001327.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值