c\c++编程-实现哈夫曼编码

哈夫曼编码(Huffman Coding),这是一种广泛使用的数据压缩技术。哈夫曼编码通过为常见的数据分配较短的编码,而为不常见的数据分配较长的编码,从而实现有效的数据压缩。

基本代码框架:

  1. 构建哈夫曼树(Huffman Tree)

    • 输入为一系列叶子节点,每个节点有一个权值,通常代表该字符在待编码字符串中出现的频率。
    • 程序首先构建一个哈夫曼树。在这个树中,较轻的节点更接近树的根,而较重的节点则更远离根。这样做的结果是最常见的数据(权重最重的节点)有最短的路径,而不常见的数据(权重最轻的节点)有最长的路径。
  2. 生成哈夫曼编码(Huffman Coding)

    • 一旦哈夫曼树被构建,程序就会为每个字符生成一个唯一的二进制编码。
    • 这些编码是通过从树的根到每个叶子节点的路径生成的。沿着路径向左移动表示一个“0”,向右移动表示一个“1”。
    • 这样,每个叶子节点(代表一个字符)都会有一个对应的唯一的二进制编码。
  3. 内存管理

    • 程序中使用了动态内存分配(malloc)来创建哈夫曼树和存储编码。
    • 适当的内存管理确保程序运行时不会出现内存泄露。
  4. 用户交互

    • 程序允许用户输入叶子节点的数量和每个节点的权值。
    • 然后,它输出每个叶子节点对应的哈夫曼编码。

 源代码:

#include<iostream>
#include<cstring>
using namespace std;

// 定义哈夫曼树的结点结构
typedef struct {
    int weight;  // 结点的权值
    int parent, lchild, rchild;  // 父节点、左孩子、右孩子的索引
} HTNode, *HufTree;
typedef char** HuffmanCode;

// 选择两个权值最小且未被选中的结点
void Select(HufTree HT, int i, int &s1, int &s2) {
    int j;
    int mindex1 = 0, mindex2 = 0;
    HT[0].weight = 999;
    for (j = 1; j <= i - 1; j++) {
        if (HT[j].parent == 0) {
            if (HT[mindex1].weight > HT[j].weight) {
                mindex1 = j;
            }
        }
    }
    for (j = 1; j <= i - 1; j++) {
        if (HT[j].parent == 0 && j != mindex1) {
            if (mindex2 == 0 || HT[mindex2].weight > HT[j].weight) {
                mindex2 = j;
            }
        }
    }
    s1 = mindex1;
    s2 = mindex2;
}

// 构建哈夫曼树并生成哈夫曼编码
void HufCode(int n, int* w, HufTree &HT, HuffmanCode &HC) {
    int m, i;
    int s1, s2, start, c, f;
    char* cd;
    HufTree p;
    if (n <= 1) {
        return;
    }
    m = 2 * n - 1;
    HT = (HufTree)malloc((m+1) * sizeof(HTNode));
    if (HT == NULL) {
        cout << "空间分配失败";
        exit(0);
    }
    for (i = 1; i <= n; i++) {
        HT[i].weight = w[i-1];
        HT[i].lchild = 0;
        HT[i].rchild = 0;
        HT[i].parent = 0;
    }
   for (; i <= m; i++) {
    HT[i].weight = 0;
    HT[i].parent = 0;
    HT[i].lchild = 0;
    HT[i].rchild = 0;
   }

    
    for (i = n + 1; i <= m; i++) {
        Select(HT, i, s1, s2);
        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;
    }

    HC = (HuffmanCode)malloc((n + 1) * sizeof(char*));
    if (HC == NULL) {
        cout << "空间分配失败";
        exit(0);
    }
    cd = (char*)malloc(n * sizeof(char));
    if (cd == NULL) {
        cout << "空间分配失败";
        exit(0);
    }
    cd[n - 1] = '\0';
    for (i = 1; i <= n; i++) {
        start = n - 1;
        for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent) {
            if (HT[f].lchild == c) {
                cd[--start] = '0';
            } else {
                cd[--start] = '1';
            }
        }
        HC[i] = (char*)malloc((n - start) * sizeof(char));
        if (HC[i] == NULL) {
            cout << "空间分配失败";
            exit(0);
        }
        strcpy(HC[i], &cd[start]);
    }
    free(cd);
}

int main() {
    int n, i;
    int w[100];
    HuffmanCode HC;
    HufTree HT;
    cout << "请输入叶子节点数:";
    cin >> n;
    
    cout << "请依次输入各个结点权值(空格隔开):";
    for (i = 0; i < n; i++) {
        cin >> w[i];
    }
    if (n == 1) {
        cout << "只有一个结点,其编码为:0" << endl;
        return 0;
    }
    else if (n > 1) {
        HufCode(n, w, HT, HC);
        for (i = 1; i <= n; i++) {
            cout << "第" << i << "个结点哈夫曼编码为:" << HC[i] << endl;
        }
        return 0;
    }
}

 运行结果

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值