数据结构之赫夫曼编码和译码(C实现)

运行效果图

运行效果图

代码

/*
数据结构之赫夫曼编码和译码(C实现) 
编译器:dev-c++ 5.11
运行环境:win10 64bit
时间:2018-5-22 13:00 至 2018-5-23 22:55
By:Wain
At:STU 
*/

#include<malloc.h>
#include<string.h>
#include<stdio.h>

typedef struct {
    unsigned int weight;    //权重(均大于0),为什么是整型?可以其它型吗?
    unsigned int parent, lchild, rchild;
}HTNode, *HuffmanTree;    //动态分配数组存储哈夫曼树
typedef char **HuffmanCode;    //动态分配数组存储哈夫曼编码表

void Select(HuffmanTree HT, int i, int *s1, int *s2) {
    //在HT[0..i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2
    int min1,min2,k,j=0;
    for(k=0;k<=i-1;++k){
        if(HT[k].parent==0){
            if(j==0){
                min1 = HT[k].weight;  *s1 = k;
            }else if(j==1){
                if(HT[k].weight<min1){
                    min2 = min1;  *s2 = *s1;
                    min1 = HT[k].weight;  *s1 = k;
                }else{
                    min2 = HT[k].weight;  *s2 = k;
                }
            }else{
                if(HT[k].weight<min1){
                    min2 = min1;  *s2 = *s1;
                    min1 = HT[k].weight;  *s1 = k;
                }else if(HT[k].weight>=min1&&HT[k].weight<min2){
                    min2 = HT[k].weight;  *s2 = k;
                }
            } 
            ++j;
        }
    }
}

void HuffmanCoding(HuffmanTree *HT, HuffmanCode *HC, int *w, int n) {
    //w存放n个字符的权值(均>0),构造哈夫曼树HT,并求出n个字符的哈夫曼编码HC

    if (n <= 1)return;

    int m = 2*n-1;    //赫夫曼树有m个结点 
    (*HT) = (HuffmanTree)malloc(m*sizeof(HTNode));
    HuffmanTree p = (*HT);
    int i;
    for (i=0; i<n; ++i, ++p, ++w) {
        //*p = {*w,0,0,0};    //C语言貌似不能这样赋值呢 
        p->weight = *w;
        p->parent = 0; p->lchild = -1; p->rchild = -1;
    }
    for (; i<m; ++i, ++p) {
        //*p = {0,0,0,0};
        p->weight = 0;
        p->parent = 0; p->lchild = 0; p->rchild = 0;
    }

    for (i=n; i<m; ++i) {    //建哈夫曼树 
        //在HT[0..i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2
        unsigned int s1, s2;
        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*sizeof(char *));
    char *cd = (char*)malloc(n * sizeof(char));
    cd[n - 1] = '\0';
    int start, f, c;
    for (i=0; 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));
        strcpy((*HC)[i], &cd[start]);
    }
    free(cd);
}




int main() {
    int n, i;
    printf("请输入需编码的字符数目n:\n"); 
    scanf_s("%d", &n);fflush(stdin);
    char *c = (char*)malloc(n * sizeof(char));    //存字符 
    int *w = (int*)malloc(n * sizeof(int));    //存权重 
    printf("请用输入字符和对应的权值(重复%d次)\n",n);
    for (i = 0; i<n; i++){
        scanf("%c %d", &c[i], &w[i]);
        fflush(stdin);
    }

    HuffmanTree HT;
    HuffmanCode HC;
    HuffmanCoding(&HT, &HC, w, n);
    printf("\n各字符对应的编码为:\n");
    for(i=0; i<n; ++i){
        printf("%c %s\n",c[i],HC[i]);
    } 

    char str[1000]; //存01二进制流 
    printf("\n请输入一串01二进制流:\n");
    scanf("%s",&str);
    char *s = str;
    int p; 
    printf("译码为:\n");
    while(*s!='\0'){
        p = 2*n-2;
        while(HT[p].lchild!=-1 || HT[p].rchild!=-1){
            if(*s=='0') p = HT[p].lchild;   //左走
            else p = HT[p].rchild;  //右走
            ++s;
        }
        printf("%c",c[p]);
    }

    free(c);
    free(w);
    return 0;
}

参考

《数据结构(C语言版)》严蔚敏、吴伟民 ———算法 6.12

哈夫曼编码译码 包括默认编码 和 自定义编码 数据结构课程设计 一、题目: 哈夫曼编码/译码的设计与实现 二、目的与要求 1、目的: 通过布置具有一定难度的实际程序设计项目,使学生进一步理解和掌握课堂上所学各种基本抽象数据类型的逻辑结构、存储结构和操作实现算法,以及它们在程序中的使用方法;使学生掌握分析问题,求解问题的方法并提高学生设计编程实现的能力。 2、要求: 基本要求: 1. 要求利用C\C++语言来完成系统的设计; 2. 突出C语言的函数特征(以多个函数实现每一个子功能)或者C++语言面向对象的编程思想; 3. 画出功能模块图; 4. 进行简单界面设计,能够实现友好的交互; 5. 具有清晰的程序流程图和数据结构的详细定义; 6. 熟练掌握C语言或者C++语言的各种操作。 创新要求: 在基本要求达到后,可进行创新设计,如系统用户功能控制,改进算法的实现实现友好的人机交互等等 三、问题描述和求解方法: 首先根据给定的n个权值构造哈夫曼树。通过遍历此二叉树完成哈夫曼编码。 四、解题过程 1. 分析程序的功能要求,划分程序功能模块。 2. 画出系统流程图。 3. 代码的编写。定义数据结构和各个功能子函数。 4. 程序的功能调试。 5. 完成系统总结报告以及使用说明书 五、进度安排 此次课程设计时间为一周,分以下几个阶段完成: 1. 选题与搜集资料:每人选择一题,进行课程设计课题的资料搜集。 2. 分析与概要设计:根据搜集的资料,进行程序功能与数据结构分析,并选择合适的数据结构、并在此基础上进行实现程序功能的算法设计。 3. 程序设计:运用掌握C/C++语言编写程序,实现各个模块功能。 4. 调试与测试:调试程序,并记录测试情况。 5. 完成课程设计报告。 6. 验收与评分:指导教师对每个同学的开发的系统进行综合验收,并由学院考核小组进行随机抽查评分。 六、撰写课程设计报告或课程设计总结 课程设计报告要求: 课程设计报告要求规范书写,应当包括如下6个部分: 1. 问题描述 2. 基本要求 3. 系统分析与设计 4. 测试数据及结果 5. 总结 6. 附录:源程序清单 七、答辩与评分标准: 1 、作业文档: 50 分; 2 、基本功能和要求: 20 分; 2 、设计报告及使用说明书: 10 分; 3 、设置错误或者按照要求改变结果: 10 分; 4 、回答问题: 10 分。 八、参考资料 《数据结构(C语言版)》 网上相关资料(....略) printf("---------------------------------------------\n"); printf(" 哈夫曼编码译码 \n"); printf(" 1.使用默认初始化 \n"); printf(" 2.使用自定义初始化 \n"); printf(" 3.进行哈夫曼编码 \n"); printf(" 4.进行哈夫曼译码 \n") ; printf(" 5.退出哈夫曼操作 \n"); printf(" 请输入1.2.3.4.5 \n"); printf(" ---------------------------------------------\n");
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

想想你说过的话

最喜欢你一言不合就打赏的样子了

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

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

打赏作者

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

抵扣说明:

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

余额充值