哈夫曼树编解码

哈夫曼树编解码

题目:

思路:

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

using namespace std;

typedef struct Node{
    char data = '\0';
    int parent = 0;
    int leftChild = 0;
    int rightChild = 0;
    int weight = 0;
}Node;

typedef struct HaffmanTree{
    Node node[1000];
    int num;
}Tree;

void createTree(Tree *tree);
int findTwoMin(Tree *tree, int *min1, int *min2, int *weight);
int encode(Tree *tree, int *code, char *str, int length);
void decode(Tree *tree, int *code, char *deStr, int length);

int main()
{
    Tree tree;
    createTree(&tree);

    char c;
    char str[1000];
    c = getchar();
    c = getchar();
    int index = 0;

    while(c != '\n'){
        str[index++] = c;
        c = getchar();
    }

    int code[1000];
    index = encode(&tree, code,  str, index);
    char deStr[100];
    decode(&tree, code, deStr, index);


//    for(int i=0; i<index; i++){
//        printf("%c ", str[i]);
//    }
    return 0;
}

void createTree(Tree *tree){
    char c;
    scanf("%d", &(tree->num));
    scanf("%c", &c);
//    printf("end num: %d\n", tree->num);

    for(int i=1; i<=tree->num; i++){
        scanf("%c",&(tree->node[i].data));
        scanf("%c", &c);
//        printf("index: %d ", i);
    }
//    printf("end char\n");
    for(int i=1; i<=tree->num; i++){
        scanf("%d",&(tree->node[i].weight));
    }
//    printf("end weight\n");
    int min1, min2;
    int weight;
    while(findTwoMin(tree, &min1, &min2, &weight)){
        ++(tree->num);
        tree->node[tree->num].leftChild = min1;
        tree->node[tree->num].rightChild = min2;
        tree->node[tree->num].weight = weight;
        tree->node[min1].parent = tree->num;
        tree->node[min2].parent = tree->num;
    }
    /*
    printf("---------------------------------------------------\n");
    printf("the tree's profile is: \n");
    printf("the node in this tree is: %d\n", tree->num);
    for(int i=1; i<=tree->num; i++){
        printf("%d's parent is: %d\n", i, tree->node[i].parent);
    }
    */
}

int findTwoMin(Tree *tree, int *min1, int *min2, int *weight){
    int minWeight1 = 99999;
    int minWeight2 = 99999;
    int temp;
    for(int i=1; i<= tree->num; i++){
        if(0 == tree->node[i].parent){
            temp = tree->node[i].weight;
            if(temp < minWeight2){
                if(temp > minWeight1){
                    minWeight2 = temp;
                    *min2 = i;
                }else{
                    minWeight2 = minWeight1;
                    minWeight1 = temp;
                    *min2 = *min1;
                    *min1 = i;
                }
            }
        }
    }

    if((minWeight1 != 99999) && (minWeight2 != 99999)){
        *weight = tree->node[*min1].weight + tree->node[*min2].weight;
        return 1;
    }else{
        return 0;
    }
}

int encode(Tree *tree, int *code, char *str, int length){
    int index = 0;
    int parent;
    for(int i=length-1; i>=0; i--){
        for(int j=1; j<=tree->num; j++){
            if(tree->node[j].data == str[i]){
                parent = j;

                //printf("the %d char is %c\n", i+1, str[i]);
                //printf("the parent is: %d\n", parent);

                break;
            }
        }
        while(tree->node[parent].parent){
            if(tree->node[tree->node[parent].parent].leftChild == parent){
                code[index] = 0;
            }else{
                code[index] = 1;
            }
            //printf("\tthe parent is: %d\n", parent);
            index++;
            parent = tree->node[parent].parent;
        }
    }
    for(int i=index-1; i>=0; i--){
        printf("%d",code[i]);
    }
    printf("\n");
    return index;
}

void decode(Tree *tree, int *code, char *deStr, int length){
    int head = tree->num;
    int cur = head;
    int index = 0;
    for(int i=length-1; i>=0; i--){
        if(code[i] == 0){
            cur = tree->node[cur].leftChild;
            if(tree->node[cur].leftChild == 0){
                deStr[index] = tree->node[cur].data;
                index++;
                cur = head;
                //printf("第%d次存储%c\n", index, deStr[index-1]);
            }
        }else{
            cur = tree->node[cur].rightChild;
            if(tree->node[cur].rightChild == 0){
                deStr[index] = tree->node[cur].data;
                index++;
                cur = head;
                //printf("第%d次存储%c\n", index, deStr[index-1]);
            }
        }
    }

    for(int i=0; i<index; i++){
        printf("%c", deStr[i]);
    }
    printf("\n");
}

运行结果:


以上

编解码就不说了,程序里有

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tailor_long

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值