HuffmanTree以及其编码

#include<stdio.h>
#include<limits.h>
#include<stdlib.h>
#include<string.h>
struct node
{
    int  w;
    int  lc,rc;
    bool flag;
    char* str;
};
node* vex;
int sum;
void initvex(int num)
{
    vex = (node*)malloc(sizeof(node)*sum);
    // 初始化n个带权结点
    for(int i=0;i<num;i++)
    {
        int cur;
        scanf("%d",&cur);
        (vex+i)->w = cur;
        (vex+i)->lc = -1;
        (vex+i)->rc = -1;
        (vex+i)->flag = true;
        (vex+i)->str = (char*)malloc(sizeof(char)*num);
    }
    for(int i=num;i<sum;i++)
    {
        (vex+i)->w = INT_MAX;
        (vex+i)->lc = -1;
        (vex+i)->rc = -1;
        (vex+i)->flag = false;
        (vex+i)->str = (char*)malloc(sizeof(char)*num);
    }
    return;
}
int search_low()
{
    int cur_min = INT_MAX;
    int mark= 0;
    // 从头遍历比较,
    for(int i=0;i<sum;i++)
    {
        if((vex+i)->flag&&((vex+i)->w)<cur_min)
        {
            mark = i;
            cur_min = (vex+i)->w;
        }
    }
    return mark;
}
bool check_leaf(int n)
{
    if((vex+n)->lc==-1&&(vex+n)->rc==-1)
        return true;
    return false;
}
// 递归—先跟遍历,输出各个结点的编码
void print(int n)
{
    if(check_leaf(n)){
        printf("%d\n",(vex+n)->w);
        printf("%s\n",(vex+n)->str);
    }
    if((vex+n)->lc!=-1)
    {
        print((vex+n)->lc);
    }
    if((vex+n)->rc!=-1)
    {
        print((vex+n)->rc);
    }
    return;
}
// 递归—从跟开始编码
// 左儿子在双亲基础上+‘0’;右儿子在双亲基础上+‘1’
void code(int parent)
{
    int parent_len = strlen((vex+parent)->str);
    int j,k;
    if((vex+parent)->lc != -1)
    {
        int i = (vex+parent)->lc;
        j=0,k=0;
        while(j<parent_len)
        {
          ((vex+i)->str)[k] = ((vex+parent)->str)[j];
          ++j,++k;
        }
        ((vex+i)->str)[k] = '0';
        ((vex+i)->str)[++k] = '\0';
        code(i);
    }
    if((vex+parent)->rc != -1)
    {
        int i = (vex+parent)->rc;
        j=0,k=0;
        while(j<parent_len)
        {
          ((vex+i)->str)[k] = ((vex+parent)->str)[j];
          ++j,++k;
        }
        ((vex+i)->str)[k] = '1';
        ((vex+i)->str)[++k] = '\0';
        code(i);
    }
    return;
}


int main()
{
    int num;
    scanf("%d",&num);
    sum = 2*num-1; // 空白结点个数为n-1
    initvex(num);
    int i,j; // 两个最小值坐标
    // num成为标志位,空白结点的填补情况
    while(num < sum)
    {
        i = search_low();
        (vex+i)->flag = false;
        j = search_low();
        (vex+j)->flag = false;
        (vex+num)->w = (vex+i)->w+(vex+j)->w;
        (vex+num)->lc = i;
        (vex+num)->rc = j;
        (vex+num)->flag = true;
        num++; // 标志位后移
    }
    num--;
    (vex+num)->str = "\0";
    code(num);print(num);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zm_zsy/article/details/78760236