c语言 哈夫曼编码

#include <stdio.h>
#include <stdlib.h>
#define MAXSYMBS 68               //字符种数or叶子数+1
#define MAXNODE 133              //结点数:算出来m=67,父结点数为2*67-1=133仅对此文档有效,2*maxsymbs-1


void rate();   //求字符在文章中出现的频率
void sort();   //排序
void huffmantree();//构造哈夫曼树
void table();            //建立码表
void huffmancode();      //哈夫曼编码
void code_txt();         //对文档编码
void decode_txt();	//解码

int n[127] = {0};                        //字符出现的次数
double symbrate[127] = {0};              //字符出现的频率
int num = 0;                             //字符总数
int m = 0;                               //字符种数or叶子数
int code_num = 0;                       //编码总数

struct huffnode
{
    int weight;   //权重
    int flag;	  //标志
    int parent;	   //父结点
    int lchild;	   //左孩子
    int rchild;    //右孩子
} huff_node[MAXNODE];
struct huffcode
{
    int bits[MAXSYMBS];
    int start;
} huff_code[MAXSYMBS], cd;

struct tab            //码表结构
{
    char ch;
    int ch_num;
} tab[MAXSYMBS];

int main()
{
    rate();
    sort();
    huffmantree();
    huffmancode();
    table();
    code_txt();
    decode_txt();
    getchar();
    return 0;
}

void rate()
{
    FILE *fp, *out;
    char c;
    int i;

    if((fp=fopen("Project_huffman.txt","r"))==NULL)
    {
        printf("Project_huffman.txt文件打开失败..\n");
        return ;
    }
    while(!feof(fp))
    {
        c = fgetc(fp);
        for(i=0; i<=127; i++)
        {
            if(c == i)
      
### 哈夫曼编码的C语言实现 哈夫曼编码是一种基于字符出现频率构建最优前缀码的算法,其核心思想是通过构建哈夫曼树来生成每个字符的编码[^1]。以下是完整的C语言实现示例代码,包含哈夫曼树的构建、编码生成和译码功能。 #### 代码实现 以下代码展示了如何在C语言中实现哈夫曼编码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXNODES 100 typedef struct { unsigned int weight; unsigned int parent, lchild, rchild; } HTNode, *HuffmanTree; typedef char **HuffmanCode; // 初始化哈夫曼树 void InitHuffmanTree(HuffmanTree ht, int n) { for (int i = 0; i < 2 * n - 1; i++) { ht[i].weight = 0; ht[i].parent = ht[i].lchild = ht[i].rchild = -1; } } // 构建哈夫曼树 void CreateHuffmanTree(HuffmanTree ht, int *w, int n) { int m = 2 * n - 1; InitHuffmanTree(ht, n); for (int i = 0; i < n; i++) { ht[i].weight = w[i]; } for (int i = n; i < m; i++) { int s1 = -1, s2 = -1; int min1 = INT32_MAX, min2 = INT32_MAX; for (int j = 0; j < m; j++) { if (ht[j].weight > 0 && ht[j].parent == -1) { if (ht[j].weight < min1) { min2 = min1; s2 = s1; min1 = ht[j].weight; s1 = j; } else if (ht[j].weight < min2) { min2 = ht[j].weight; s2 = j; } } } ht[s1].parent = i; ht[s2].parent = i; ht[i].lchild = s1; ht[i].rchild = s2; ht[i].weight = ht[s1].weight + ht[s2].weight; } } // 生成哈夫曼编码 void GenerateHuffmanCode(HuffmanTree ht, HuffmanCode hc, int n) { char *cd = (char *)malloc(n * sizeof(char)); cd[n - 1] = '\0'; for (int i = 0; i < n; i++) { int start = n - 1; int c = i, p = ht[i].parent; while (p != -1) { if (ht[p].lchild == c) cd[--start] = '0'; else cd[--start] = '1'; c = p; p = ht[c].parent; } hc[i] = (char *)malloc((n - start) * sizeof(char)); strcpy(hc[i], &cd[start]); } free(cd); } // 打印哈夫曼编码 void PrintHuffmanCode(HuffmanTree ht, HuffmanCode hc, int n) { printf("字符\t权重\t编码\n"); for (int i = 0; i < n; i++) { printf("%d\t%d\t%s\n", i, ht[i].weight, hc[i]); } } int main() { int n = 6; // 字符数量 int w[] = {5, 9, 12, 13, 16, 45}; // 权重数组 HuffmanTree ht = (HuffmanTree)malloc(2 * n - 1 * sizeof(HTNode)); HuffmanCode hc = (HuffmanCode)malloc(n * sizeof(char *)); CreateHuffmanTree(ht, w, n); GenerateHuffmanCode(ht, hc, n); PrintHuffmanCode(ht, hc, n); for (int i = 0; i < n; i++) { free(hc[i]); } free(hc); free(ht); return 0; } ``` #### 代码说明 1. **哈夫曼树初始化**:`InitHuffmanTree`函数用于初始化哈夫曼树节点的权重、父节点、左右子节点信息。 2. **构建哈夫曼树**:`CreateHuffmanTree`函数根据输入的权重数组构建哈夫曼树,通过选择最小的两个节点并合并为新节点的方式完成。 3. **生成哈夫曼编码**:`GenerateHuffmanCode`函数从叶子节点到根节点逆向生成每个字符的编码。 4. **打印编码结果**:`PrintHuffmanCode`函数输出每个字符及其对应的哈夫曼编码。 #### 示例输出 假设输入权重为 `{5, 9, 12, 13, 16, 45}`,运行程序后可能得到如下输出: ``` 字符 权重 编码 0 5 11111 1 9 11110 2 12 1110 3 13 110 4 16 10 5 45 0 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值