c语言哈夫曼编码译码系统 c语言 一个完整的系统具有以下功能: (1)I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件h

c语言哈夫曼编码译码系统

c语言
一个完整的系统具有以下功能:
(1)I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。
(2)E:编码(Encoding)。利用已建好的哈夫曼树(如不在内存,则从文件htmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
(3)D:译码(Decoding)。利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。
(4)P:打印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
(5)T:打印哈夫曼树(TreePrinting)。将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
3)测试数据
新建一个.txt文件,用来存放待处理的数据,这些数据为ASCII码值的集合,而且每种字符的数量并不能相同。本实验拟设其中的数据为1个a,两个b,三个c,四个d,五个e,六个f。
以下是一个简单的C语言实现的哈夫曼编码译码系统的代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义哈夫曼树节点
typedef struct Node {
    
    
    unsigned char ch;
    int weight;
    struct Node* left;
    struct Node* right;
} Node;
// 定义哈夫曼编码表
typedef struct {
    
    
    unsigned char ch;
    char code[256];
} CodeTable;
// 初始化哈夫曼树
Node* initHuffmanTree(int n, unsigned char* chars, int* weights) {
    
    
    Node** nodes = (Node**)malloc(n * sizeof(Node*));
    for (int i = 0; i < n; i++) {
    
    
        nodes[i] = (Node*)malloc(sizeof(Node));
        nodes[i]->ch = chars[i];
        nodes[i]->weight = weights[i];
        nodes[i]->left = NULL;
        nodes[i]->right = NULL;
    }
    while (n > 1) {
    
    
        int min1 = 0, min2 = 1;
        if (nodes[min1]->weight > nodes[min2]->weight) {
    
    
            int temp = min1;
            min1 = min2;
            min2 = temp;
        }
        for (int i = 2; i < n; i++) {
    
    
            if (nodes[i]->weight < nodes[min1]->weight) {
    
    
                min2 = min1;
                min1 = i;
            } else if (nodes[i]->weight < nodes[min2]->weight) {
    
    
                min2 = i;
            }
        }
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->ch = 0;
        newNode->weight = nodes[min1]->weight + nodes[min2]->weight;
        newNode->left = nodes[min1];
        newNode->right = nodes[min2];
        nodes[min1] = newNode;
        nodes[min2] = nodes[n - 1];
        n--;
    }
    return nodes[0];
}
// 生成哈夫曼编码表
void generateCodeTable(Node* root, CodeTable* table, char* code, int depth) {
    
    
    if (root->left == NULL && root->right == NULL) {
    
    
        code[depth] = '\0';
        for (int i = 0; i < 256; i++) {
    
    
            if (table[i].ch == root->ch) {
    
    
                strcpy(table[i].code, code);
                break;
            }
        }
    } else {
    
    
        code[depth] = '0';
        generateCodeTable(root->left, table, code, depth + 1);
        code[depth] = '1';
        generateCodeTable(root->right, table, code, depth + 1);
    }
}
// 编码
void encode(Node* root, CodeTable* table, char* text, FILE* outputFile) {
    
    
    char* code = (char*)malloc(256 * sizeof(char));
    int index = 0;
    for (int i = 0; text[i] != '\0'; i++) {
    
    
        for (int j = 0; j < 256; j++) {
    
    
            if (table[j].ch == text[i]) {
    
    
                strcpy(code + index, table[j].code);
                index += strlen(table[j].code);
                break;
            }
        }
    }
    code[index] = '\0';
    fprintf(outputFile, "%s", code);
    free(code);
}
// 译码
void decode(Node* root, char* code, FILE* outputFile) {
    
    
    Node* curr = root;
    for (int i = 0; code[i] != '\0'; i++) {
    
    
        if (code[i] == '0') {
    
    
            curr = curr->left;
        } else {
    
    
            curr = curr->right;
        }
        if (curr->left == NULL && curr->right == NULL) {
    
    
            fprintf(outputFile, "%c", curr->ch);
            curr = root;
        }
    }
}
// 打印代码文件
void printCodeFile(FILE* codeFile) {
    
    
    int count = 0;
    unsigned char ch;
    while ((ch = fgetc(codeFile)) != EOF) {
    
    
        printf("%c", ch);
        count++;
        if (count % 50 == 0) {
    
    
            printf("\n");
        }
    }
    printf("\n");
}
// 打印哈夫曼树
void printHuffmanTree(Node* root, int depth) {
    
    
    if (root == NULL) {
    
    
        return;
    }
    printHuffmanTree(root->right, depth + 1);
    for (int i = 0; i < depth; i++) {
    
    
        printf("    ");
    }
    if (root->ch == 0) {
    
    
        printf("*\n");
    } else {
    
    
        printf("%c\n", root->ch);
    }
    printHuffmanTree(root->left, depth + 1);
}
int main() {
    
    
    int n;
    printf("Enter the number of characters: ");
    scanf("%d", &n);
    unsigned char* chars = (unsigned char*)malloc(n * sizeof(unsigned char));
    int* weights = (int*)malloc(n * sizeof(int));
    printf("Enter the characters and weights:\n");
    for (int i = 0; i < n; i++) {
    
    
        scanf(" %c %d", &chars[i], &weights[i]);
    }
    Node* root = initHuffmanTree(n, chars, weights);
    CodeTable* table = (CodeTable*)malloc(256 * sizeof(CodeTable));
    char code[256];
    generateCodeTable(root, table, code, 0);
    FILE* hfmTreeFile = fopen("hfmTree", "w");
    fwrite(root, sizeof(Node), 1, hfmTreeFile);
    fclose(hfmTreeFile);
    FILE* codeFile = fopen("CodeFile", "w");
    char text[256];
    printf("Enter the text to be encoded: ");
    scanf(" %[^\n]", text);
    encode(root, table, text, codeFile);
    fclose(codeFile);
    codeFile = fopen("CodeFile", "r");
    printf("CodeFile content:\n");
    printCodeFile(codeFile);
    fclose(codeFile);
    FILE* textFile = fopen("TextFile", "w");
    codeFile = fopen("CodeFile", "r");
    char codeText[256];
    fscanf(codeFile, "%s", codeText);
    decode(root, codeText, textFile);
    fclose(codeFile);
    fclose(textFile);
    FILE* treePrintFile = fopen("TreePrint", "w");
    printHuffmanTree(root, 0);
    fclose(treePrintFile);
    free(chars);
    free(weights);
    free(table);
    return 0;
}

以上代码实现了一个简单的哈夫曼编码译码系统。你可以根据自己的需求进行修改和完善。请注意,此代码示例中的输入和输出文件名是固定的,你可以根据需要进行调整。同时,该示例中使用的是字符型的权值,如果需要处理其他类型的权值,请适当修改代码。
希望以上代码能帮助到你实现哈夫曼编码译码系统。如果有任何问题,请随时向我提问。

猜你喜欢

转载自blog.csdn.net/zezeaichirou/article/details/134627068