哈夫曼编码-译码器

此次实验的注释解析多加不少---若对小伙伴们有帮助 希望各位麻烦点个关注 多谢

1.哈夫曼树构造算法为:

  (1)由给定的n个权值{w1,w2,…,wn}构造n棵只有根结点的二叉树,从而得到一个二叉树森林F={T1,T2,…,Tn}。
  (2)在二叉树森林F中选取根结点的权值最小和次小的两棵二叉树作为新的二叉树的左右子树构造新的二叉树,新的二叉树的根结点权值为左右子树根结点权值之和。
  (3)在二叉树森林F中删除作为新二叉树左右子树的两棵二叉树,将新二叉树加入到二叉树森林F中。
  (4)重复步骤(2)和(3),当二叉树森林F中只剩下一棵二叉树时,这棵二叉树就是所构造的哈夫曼树。

2.编程实战:

[问题描述](设计性实验)

哈夫曼树很易求出给定字符集及其概率(或频度)分布的最优前缀码。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。该技术一般可将数据文件压缩掉20%至90%,其压缩效率取决于被压缩文件的特征。

利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时,降低传输成本。但是,这要求在发送端通过一个编码系统对待传送电文须预先编码,在接收须将传送来的数据进行译码。请自行设计实现一个具有初始化、编码、译码、输入/输出等功能的哈夫曼码的编码/译码系统。并实现以下报文的编码和译码:“this program is my favorite”。

[测试数据]

某通信的电文字符集为26个英文字母及空格字符,其出现频度如下表所示:

1、设计思想描述

(1)   问题分析。

先对输入的字符串进行操作

再利用haffman编码进行存储转译

实现节省传输成本

(2)  哈夫曼树中各结点的结构描述(提示:图示)。

(3)   哈夫曼树的存储结构描述(提示:分析采用顺序存储还是利用链式存储等)。

   顺序存储

2、主要算法设计与实现

[要求]

1、利用类模板来实现。

2、类中各成员函数要求给出自行设计的算法步骤描述及主要设计思想。

3、给出类中各成员函数算法设计实现。

4、对自行设计的各算法进行评估(提示:时间复杂度、空间复杂度等)。

答:

Haffman(int weight[], int n);                   //构造函数  时间复杂度O(n)

Code* HaffmanCode(int n,Code* haffCode,char* c);//将haffman进行编码  时间复杂度O(n^2)

ps:此处就计算所得的 时间复杂度来看有待改善

void encoding(int n,Code* haffCode);            //输出权值与编码  时间复杂度O(n)

void decoding(int n,Code* haffCode);            //输出译文  时间复杂度O(n)

3、代码实现

结构体构造

HaffNode-结点结构、Code-编码的数据元素结构

struct HaffNode                      //哈夫曼树的结点结构
{int weight;            //权值int flag;                //标记int parent;            //双亲结点下标int leftChild;            //左孩子下标int rightChild;            //右孩子下标
};
struct Code              //存放哈夫曼编码的数据元素结构
{int bit[MaxN];            //数组int start;            //编码的起始下标int weight;            //字符的权值char data;
};

Haffman类构造

#include <iostream>
using namespace std;
class Haffman
{HaffNode *hn;//= new HaffNode[2*n+1];Code *code;//=new Code[n];int n;
public:Haffman(int weight[], int n);                   //构造函数  时间复杂度O(n)Code* HaffmanCode(int n,Code* haffCode,char* c);//将haffman进行编码  时间复杂度O(n^2)void encoding(int n,Code* haffCode);            //输出权值与编码  时间复杂度O(n)void decoding(int n,Code* haffCode);            //输出译文  时间复杂度O(n)
};
Haffman::Haffman(int weight[], int n)
//建立叶结点个数为n权值为weight的哈夫曼树haffTree
{hn= new HaffNode[2*n+1];int j, m1, m2, x1, x2;
//哈夫曼树haffTree初始化。n个叶结点的哈夫曼树共有2n-1个结点for(int i = 0; i < 2 * n - 1 ; i++){if(i < n)hn[i].weight = weight[i];elsehn[i].weight = 0;hn[i].parent = 0;hn[i].flag   = 0;hn[i].leftChild = -1;hn[i].rightChild = -1;}for(int i = 0;i < n-1;i++){m1 = m2 = MaxValue;x1 = x2 = 0;for(j = 0; j < n+i;j++){if(hn[j].weight < m1 && hn[j].flag == 0){m2 = m1;  //m2放权值第2小的权值x2 = x1;  //m2放权值第2小的下标m1 = hn[j].weight;  //更新m1x1 = j;  //更新x1,下标
            }else if(hn[j].weight < m2 && hn[j].flag == 0){m2 = hn[j].weight;x2 = j;}}//将找出的两棵权值最小的子树合并为一棵子树hn[x1].parent  = n+i;hn[x2].parent  = n+i;hn[x1].flag    = 1;hn[x2].flag    = 1;hn[n+i].weight =hn[x1].weight+hn[x2].weight;hn[n+i].leftChild = x1;hn[n+i].rightChild = x2;}
}
//哈夫曼编码算法如下:
Code* Haffman::HaffmanCode(int n,Code* haffCode,char* c)
//由n个结点的哈夫曼树haffTree构造哈夫曼编码haffCode
{int child,parent;code=new Code[n];//求n个叶结点的哈夫曼编码for(int i = 0; i < n; i++){code->start = n-1;                       //不等长编码的最后一位为n-1code->weight = hn[i].weight;    //取得编码对应权值的字符child = i;parent = hn[child].parent;//由叶结点向上直到根结点while(parent != 0){if(hn[parent].leftChild == child)code->bit[code->start] = 0;  //左孩子结点编码0elsecode->bit[code->start] = 1;  //右孩子结点编码1code->start--;child = parent;parent = hn[child].parent;}//保存叶结点的编码和不等长编码的起始位for(int j = code->start+1; j < n; j++)haffCode[i].bit[j] = code->bit[j];haffCode[i].start  = code->start;haffCode[i].weight = code->weight;        //保存编码对应的权值haffCode[i].data=c[i];                  //存储原始数据
    }return haffCode;
}
void Haffman::encoding(int n,Code* haffCode)
{for(int i = 0; i < n; i++){cout << "Weight = " << haffCode[i].weight << "   Code = ";for(int j = haffCode[i].start+1; j < n; j++)cout << haffCode[i].bit[j];cout<<endl;}
}
void Haffman::decoding(int n,Code* haffCode)
{for(int i = 0; i < n; i++)cout<<haffCode[i].data;cout<<endl;
}

主函数

#include <iostream>
#include <stdlib.h>const int MaxValue = 10000;    //初始设定的权值最大值
const int MaxBit = 4;        //初始设定的最大编码位数
const int MaxN = 30;        //初始设定的最大结点个数
#include"Haffman.h"
using namespace std;int main()
{int n;//weight[]-权重(频率)数组int weight[] = {186,64,13,22,32,103,21,15,47,57,1,5,32,20,57,63,15,1,48,51,80,23,8,18,1,16,1};//a[]-按顺序存放各个字母char a[27]={' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};char b[30];             //存放输入字符串int c[30];              //存放对应b数组的权值cout<<"请输入需要编码英文的字符串:";cin.getline(b,30);      //将输入的字符串存储在b数组中//将c数组权值与b数组字符串进行对应for(n=0;b[n]!='\0';n++){for(int l=0;l<27;l++){if(a[l]==b[n]){c[n]=weight[l];break;}}}if(n > MaxN){cout << "定义的n越界,修改MaxN! " << endl;exit(0);}//生成haffCode数组用作存储 编码后的数据Code* haffCode=new Code[n];Haffman hm(c, n);                   //调用生成Haffman树Code* co=hm.HaffmanCode(n,haffCode,b);//得到编码后数组cocout<<"编码后:"<<endl;hm.encoding(n,co);                  //对co进行遍历输出cout<<"---------------------------------------"<<endl;cout<<"译码为:"<<endl;hm.decoding(n,co);                  //对编码数组操作得到译码return 0;
}

结果:

转载于:https://www.cnblogs.com/cc123nice/p/10835957.html

c++实验8 哈夫曼编码-译码器相关推荐

  1. 实验四-哈夫曼编码的MATLAB实现

    信息论编码实验3~9连载,更多看专栏. 哈夫曼编码MATLAB实现 一.哈夫曼编码的原理 二.哈夫曼编码的实例 三.代码及运行结果 3.1根据原理自编程序 3.2利用MATLAB内嵌函数 四.程序自评 ...

  2. 霍夫曼编码实验matlab,哈夫曼编码 MATLAB程序

    clc clear fid=fopen( 'C:\Users\yichao\Desktop\新建文本文档.txt');%打开 txt 文件 [zimu]=fscanf(fid, '%c'); %读取二 ...

  3. 哈夫曼编码/译码器:设计一个哈夫曼编码/译码系统,对一个文本文件中的字符进行哈夫曼编码,生成编码文件;反过来,可将一个编码文件译码还原为一个文本文件(.txt)。要求:① 输入一个待压缩的文本文件名

    目录 1.实验题目 2.概要设计 2.1 问题分析 2.2 流程图 2.3 功能模块 3.详

  4. 数据结构哈夫曼编码解码课程设计

    数据结构课程设计 源代码在另一篇博客可以找到:https://blog.csdn.net/qq_40513633/article/details/85055411?ops_request_misc=% ...

  5. 哈夫曼编码解码课程设计源代码

    数据结构课程设计 "哈夫曼编码/译码器 设计一个利用哈夫曼算法的编码和译码系统,重复显示并处理以下项目,知道选择退出为止/ [基本要求] 1)将权值数据存放在数据文件(文件名data.txt ...

  6. 蓝桥哈夫曼树C语言,实验四 哈夫曼树及哈夫曼编码

    实验目的## 掌握哈夫曼树的概念.哈夫曼编码及其应用. 掌握生成哈夫曼树的算法. 会用哈夫曼树对传输报文进行编码. 掌握二叉树的二叉链表存储方式及相应操作的实现. ##实验内容## 用哈夫曼编码进行通 ...

  7. 数据结构实验——哈夫曼编码

    目录 问题描述 基本要求 问题分析 实验代码 运行结果 实验总结 问题描述 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本.但是,这要求在发送端通过一个编码系统对待传数据 ...

  8. 数据结构实验之二叉树六:哈夫曼编码

    Description 字符的编码方式有多种,除了大家熟悉的ASCII编码,哈夫曼编码(Huffman Coding)也是一种编码方式,它是可变字长编码.该方法完全依据字符出现概率来构造出平均长度最短 ...

  9. 夫曼编码译码系统课程设计实验报告(含源代码c++_c语言),哈夫曼编码译码系统课程设计实验报告(含源代码C++_C语言)[1]...

    目 录 摘 要 ---------------------------..------ II Abstract ----------------------------..---... II 第一章 ...

最新文章

  1. Android 10.0 PackageManagerService(二)权限扫描-[Android取经之路]
  2. 字符A-Z - ABCD...XYZ
  3. FFMPEG more samples than frame size (avcodec_encode_audio2) 的解决方案
  4. Zoom计划于4月IPO
  5. java中的topicFont_Fontmin 快速指南
  6. 从零开始学产品第六篇:更强大的测试,自动化测试和性能测试
  7. (二)AS给button添加点击事件
  8. mysql根据时间回退_MySQL 中的日期时间类型
  9. 我父亲的新发明--玉米点播器
  10. JavaScript编程语言概述
  11. J2SDK 安装配置指南
  12. nmds与mds的区别_NMDS分析
  13. 【爬虫实战】利用scrapy框架爬取豆瓣图书信息
  14. jquery ligerui php,jQuery LigerUI操作表格
  15. 我是个Java开发者,我到底要不要学大数据开发?
  16. 小程序12306服务器,微信小程序12306来了!史上最详细体验出炉!
  17. 一份超全面的机器学习公共数据集
  18. 什么是做空 什么是做空期权波动率?
  19. 对2030年的人工智能的预测#AIGC的机会到底在何处?
  20. 网站安全防护该怎么做?有什么具体措施?

热门文章

  1. android wine教程_技术|如何在 Android 上借助 Wine 来运行 Windows Apps
  2. java hbase流量日志,Spark+Hbase 亿级流量分析实战(日志存储设计)
  3. java poi读取word中附件_java poi word读取
  4. 工作组win7计算机无法访问,win7系统没有权限访问工作组计算机的解决方法
  5. hua图软件 mac_细数Mac上那些好用且免费的软件(四)
  6. 30余种加密编码类型的密文特征分析
  7. 从CTF比赛真题中学习压缩包伪加密与图片隐写术
  8. python编程基础之二十九
  9. Linux20180502 六周第四次课(5月2日)
  10. Linux Bash Shell字符串截取