数据结构实验5-哈夫曼编码

实验内容

某报文中共出现abdeoy 等6个字符,各字符出现频度依次为12 6 4 1 2 8。要求:

  1. 实现哈弗曼编码算法,对这6个字符求出各自的编码;
  2. 实现哈弗曼译码算法,对给定的一组编码(110011111101110110),译出其对应的报文部分 。

程序代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100
typedef int ElemType;
typedef int Status;
typedef int Boolean;
typedef struct {
    int weight,id;
    unsigned int parent, lchild,rchild;
}HTNode, *HuffmanTree;
typedef char * * HuffmanCode;
typedef struct{
    int w;
    char c;
}temp;
void Select(HuffmanTree & HT, int tag, int & s1, int &s2)
{
    int minnum = 1e9, pos = -1;
    for(int i = 1; i<=tag;++i){
        if(HT[i].weight<minnum && HT[i].parent == 0){
            minnum = HT[i].weight;
            pos  = i;
        }
    }
    s2 = pos;
    HT[pos].parent = tag+1;
    minnum = 1e9, pos  = -1;
    for(int i = 1;i<=tag;++i){
        if(HT[i].weight<minnum && HT[i].parent == 0){
            minnum = HT[i].weight;
            pos  = i;
        }
    }
    s1 = pos;
    HT[pos].parent = tag+1;
}
void output(HuffmanTree & HT, int m)
{
    printf("    i     w     lc    rc    pa\n");
    for(int i = 1 ;i<=m;++i){
        printf("%5d %5d %5d %5d %5d\n",i,HT[i].weight,HT[i].lchild,HT[i].rchild,HT[i].parent);
    }
}
bool cmp(HTNode h1, HTNode h2)
{
    if(h1.weight<h2.weight) return true;
    else return false;
}
bool cmpt(temp a, temp b)
{
    if(a.w > b.w) return false;
    else return true;
}
void HuffmanCoding(HuffmanTree & HT, HuffmanCode &HC, int *w , int n)
{
    if(n<=1) return;
    int m = 2 * n -1 ;
    HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));
    int i = 1;
    HuffmanTree p = HT;
    for(;i<=n; ++i,++p,++w){
        HT[i] = {*w,i,0,0,0};
    }
    for(i = n+1 ;i<=m;++i,++p)
        HT[i]= {0,i,0,0,0};
    for(int i = n+1;i<=m;++i){
        int s1, s2;
        Select(HT,i-1,s1,s2);
        if(s2<=n) swap(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 *));
    char * cd = (char *)malloc( n * sizeof(char));
    cd[n-1] = '\0';
    for(int i = 1; i<=n;++i){
        int start = n-1;
        unsigned int f = HT[i].parent;
        for( int 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);
}
void uncoding(HuffmanTree & HT, int n,char * s)
{
    char str[1000] = "110011111101110110";
    printf("|"); printf("       请输入想要解码的01串        ") ;printf("|\n");
    scanf("%s",str);
    printf("|"); printf("          译码的结果为             ") ;printf("|\n");
    int len = strlen(str);
    HuffmanTree t = &HT[2*n-1];
    for(int i = 0; i<len;++i){
        if(str[i] == '0'){
            t = &HT[t->lchild];
        }else{
            t = &HT[t->rchild];
        }
        if(t->id<=n){
            printf("%c",s[t->id-1]);
            t = &HT[2*n-1];
            continue;
        }
    }
    printf("\n");
}
void Paint()
{
    printf("|"); printf("       The Experiment Of Tree        ") ;printf("|\n");
    printf("|"); printf("              Huffman                ") ;printf("|\n");
    printf("|"); printf("        Author: pengwill             ") ;printf("|\n");
    printf("|"); printf("          Date:2017/5/3              ") ;printf("|\n");
}
int main()
{
    Paint();
    HuffmanTree HT ;
    HuffmanCode HC;
    printf("|"); printf("       请输入想要编码的字符          ") ;printf("|\n");
    char str[30] = {'a','b','d','e','o','y'};
    scanf("%s",str);
    printf("|"); printf("       请依次输入字符的频率          ") ;printf("|\n");
    int fre[30] = {12, 6, 4, 1, 2, 8};
    for(int i = 0; i<strlen(str);++i) scanf("%d",&fre[i]);
    temp t[30];
    for(int i = 0; i<strlen(str);++i){
        t[i].w = fre[i];
        t[i].c = str[i];
    }
    HuffmanCoding(HT,HC,fre,strlen(str));
    printf("|"); printf("          编码的结果为               ") ;printf("|\n");
    for(int i = 1; i<=strlen(str) ;++i){
        printf("%c : ",t[i-1].c);
        printf("%s\n",HC[i]);
    }
    printf("\n");
    uncoding(HT,strlen(str),str);
    return 0;
}

运行结果

在这里插入图片描述
哈夫曼树的结构
这里写图片描述

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值