算法分析与设计实验报告——实现哈夫曼编码

目录:

  • 算法分析与设计实验报告——实现哈夫曼编码
    • 一、 实验目的
    • 二、实验要求
    • 三、 实验原理
    • 四、 实验过程(步骤)
    • 五、 运行结果
    • 六、实验分析与讨论
    • 七、实验特色与心得
    • 附件一 实验过程(步骤)
    • 附件二 运行结果

一、 实验目的

掌握贪心算法的基本思想和解决问题的基本步骤,认识贪心算法和动态规划的联系与区别,对比解决同一问题的两种算法设计策略的时间复杂性。

二、实验要求

用c++语言实现用贪心算法解决哈夫曼编码问题,分析时间复杂性,体会贪心算法解决问题的基本思路和步骤。

三、 实验原理

1、哈夫曼树的定义:假设有n个权值,试构造一颗有n个叶子节点的二叉树,每个叶子带权值为wi,其中树带权路径最小的二叉树成为哈夫曼树或者最优二叉树;
2、哈夫曼树的构造:weight为输入的字符权值,parent为这个节点的父节点的位置,lchild为这个节点的左孩子的位置,rchild为这个节点的右孩子的位置,即每一个HTNode对应一个结点。然后根据weight的值,取出现存子树中的最小与次小的MinCode,并且这两个子树没有父节点,把他们俩相连接成为一颗新树。如此往复构造出哈夫曼树。通过已经构造出的哈夫曼树,编码时自底向上进行查找判断,直到parent为树的顶点为止。这样,根据每次向上搜索后,原节点为父节点的左孩子还是右孩子,来记录0或1,这样,每个字符都会有一个01编码与之唯一对应,并且任何编码没有前部分是同其他完整编码一样的;解码时从顶部向下查找,直到查找到叶子结点,输出对应的字符。

四、 实验过程(步骤)

见附件一
实验步骤、特点
重要源代码(流操作的部分要醒目的提示并注释)

五、 运行结果

见附件二

六、实验分析与讨论

一开始对哈夫曼树树不是很了解,构造的时候不知道如何去构造,查找资料后选择了一种以数组为主要操作对象的算法。还有这次写的程序比较长,有些变量应用错误,所以出现了很多奇怪的的bug。

七、实验特色与心得

这次试验写了很长的程序,直到我写完才发觉。这次实验让我对贪心算法与哈夫曼树有了更深的了解。而且这次程序比较长,所以我出现了应用变量错误的现象。这种错误也是我对问题的理解深度不够造成的。以后写程序要在深刻理解的基础上再动键盘。

附件一 实验过程(步骤)

#include <bits/stdc++.h>#define maxn 1000
//Format width
#define fmw 10using namespace std;
//哈夫曼树结点结构体
typedef struct {int weight;int parent;int lchild;int rchild;
} HTNode, *HuffmanTree;
//需要编码的字符串数组
static char N[maxn];
//定义哈夫曼编码数组(char型二级指针(指向指针的指针))
typedef char **HuffmanCode;
//最小与次小的结点
typedef struct {int s1;int s2;
} MinCode;//函数声明
//报错函数
void Error(string message);//哈夫曼编码函数
HuffmanCode HuffmanCoding(HuffmanTree &HT, HuffmanCode HC, int *w, int n);//选出最小与次小的函数
MinCode Select(HuffmanTree HT, int n);void Error(string message) {cout << "Error:" << message << endl;exit(1);
}//哈夫曼树,哈夫曼编码,权值数组,叶子结点数量
HuffmanCode HuffmanCoding(HuffmanTree &HT, HuffmanCode HC, int *w, int n) {int i, s1 = 0, s2 = 0;//哈夫曼树HuffmanTree p;//暂存哈夫曼编码数组char *cd;//m为总结点数int f, c, start, m;//最小与次小节点MinCode min;//如果结点只有一个,不进行编码if (n <= 1)Error("Code too small");//计算总结点数量m = 2 * n - 1;//动态创建哈夫曼树HT = (HuffmanTree) malloc((m + 1) * sizeof(HTNode));//HT前n个为叶子节点,后面n-1个为非叶子节点//初始化n个叶子节点for (p = HT, i = 0; i <= n; i++, p++, w++) {p->weight = *w;p->parent = 0;p->lchild = 0;p->rchild = 0;}//初始化从后面数n-1个非叶子节点for (; i <= m; i++, p++) {p->weight = 0;p->parent = 0;p->lchild = 0;p->rchild = 0;}//创建哈夫曼树for (i = n + 1; i <= m; i++) {//寻找最小与次小min = Select(HT, i - 1);//最小s1 = min.s1;//次小s2 = min.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;//合并权值}//输出创建的树cout << "哈夫曼树列表:" << endl;cout << setw(fmw) << left << "序号" << setw(fmw) << left << "权值" << setw(fmw) << left << "父节点" << setw(fmw) << left<< "左孩子" << setw(fmw) << left << "右孩子" << endl;for (i = 1; i <= m; i++) {cout << setw(fmw) << left << i << setw(fmw) << left << HT[i].weight << setw(fmw) << left << HT[i].parent<< setw(fmw) << left << HT[i].lchild << setw(fmw) << left << HT[i].rchild << endl;}//动态创建哈夫曼编码HC = (HuffmanCode) malloc((n + 1) * sizeof(char *));//动态创建暂存哈夫曼编码数组cd = (char *) malloc(n * sizeof(char *));//最后一位赋值为结束符cd[n - 1] = '\0';//求解编码for (i = 1; i <= n; i++) {start = n - 1;/** 左为0,右为1*///从第一号结点往上回溯查找,逆序存放for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent) {//父节点的左子树与自己比较if (HT[f].lchild == c)cd[--start] = '0';elsecd[--start] = '1';}//对第i个字符分配空间HC[i] = (char *) malloc((n - start) * sizeof(char *));//将cd暂存的复制到HCstrcpy(HC[i], &cd[start]);}free(cd);return HC;}//寻找最小与次小的结点
MinCode Select(HuffmanTree HT, int n) {//最小,次小int min, secmin;int i, s1, s2;MinCode code;s1 = 1;s2 = 1;//寻找最小值min = 0x3f3f3f3f;for (i = 1; i <= n; i++) {if (HT[i].weight < min && HT[i].parent == 0) {min = HT[i].weight;s1 = i;}}//寻找次小值secmin = 0x3f3f3f3f;for (i = 1; i <= n; i++) {if ((HT[i].weight < secmin) && (i != s1) && HT[i].parent == 0) {secmin = HT[i].weight;s2 = i;}}//封装返回code.s1 = s1;code.s2 = s2;return code;}//解码 哈夫曼树,叶子结点数,解码字符
void HuffmanTranslateCoding(HuffmanTree HT, int n, char *ch) {int m = 2 * n - 1;int i, j = 0;cout << "解码后:" << endl;//循环到最后while (ch[j] != '\0') {i = m;//从顶部向下查找while (HT[i].lchild != 0 && HT[i].rchild != 0) {if (ch[j] == '0')//向左查找i = HT[i].lchild;else//向右查找i = HT[i].rchild;j++;}//输出对应字符cout << N[i - 1];}cout << endl;
}//主函数
int main() {HuffmanTree HT = NULL;HuffmanCode HC = NULL;int *w = NULL;int i, n;char tran[maxn];cout << "请输入需要编码的字符串N:";gets(N);n = strlen(N);w = (int *) malloc((n + 1) * sizeof(int *));w[0] = 0;cout << "请依次输入权值:" << endl;for (i = 1; i <= n; i++) {printf("w[%d]=", i);cin >> w[i];}HC = HuffmanCoding(HT, HC, w, n);//打印哈夫曼编码表cout << "哈夫曼编码:" << endl;cout << setw(fmw) << left << "字符" << setw(fmw) << left << "权值" << setw(fmw) << left << "编码" << endl;for (i = 1; i <= n; i++) {cout << setw(fmw) << left << N[i - 1] << setw(fmw) << left << w[i] << setw(fmw) << left << HC[i] << endl;}cout << "哈夫曼编码:";for (i = 1; i <= n; i++) {cout << HC[i];}cout << endl;cout << "请输入需要解码的字符串T:";getchar();gets(tran);HuffmanTranslateCoding(HT, n, tran);return 0;
}
/*
abcdef4513121695*/
/*
computer
19
21
2
3
6
7
10
32*/

附件二 运行结果

算法分析与设计实验报告——实现哈夫曼编码相关推荐

  1. 算法分析与设计实验报告 ——二分搜索程序算法的实现

    算法分析与设计实验报告 --二分搜索程序算法的实现 实验目的及要求 1.理解分治算法的概念和基本要素: 2.理解递归的概念: 3.掌握设计有效算法的分治策略: 4.通过二分搜索技术学习分治策略设计技巧 ...

  2. 算法分析与设计实验报告——实现汽车加油问题

    算法分析与设计实验报告--实现汽车加油问题 目录: 算法分析与设计实验报告--实现汽车加油问题 一. 实验目的 二.实验要求 三. 实验原理 四. 实验过程(步骤) 五. 运行结果 六.实验分析与讨论 ...

  3. 算法分析与设计实验报告——二分搜索算法的实现

    算法分析与设计实验报告--二分搜索算法的实现 目录: 算法分析与设计实验报告--二分搜索算法的实现 一. 实验目的 二.实验要求 三. 实验原理 四. 实验过程(步骤) 五. 运行结果 六.实验分析与 ...

  4. 中北大学算法分析与设计实验报告一(BF算法)

    中北大学算法分析与设计实验报告一(BF算法) 1.实验名称 实验一 算法基础实验:数理基础与串匹配程序设计 2.实验目的 以字符串匹配问题为例,结合C等编程语言和链表.堆.栈等数据结构知识,基于BF算 ...

  5. 算法分析与设计实验报告

    计算机算法分析与设计实验报告 实验一:递归回溯 阶乘(Factorial) #include<iostream> using namespace std; int factorial(in ...

  6. 中北大学算法分析与设计实验报告六(最大团问题)

    中北大学算法分析与设计实验报告六(最大团问题) 1.实验名称 实验六 回溯与分支限界算法实验 2.实验目的 题目:最大团问题 强化学生利用回溯算法和优化处理实际问题的能力. 3.训练知识点集群 (1) ...

  7. 算法分析与设计实验报告三——动态规划算法

    一.实验目的 掌握动态规划方法贪心算法思想 掌握最优子结构原理 了解动态规划一般问题 二.实验内容 编写一个简单的程序,解决0-1背包问题.设N=5,C=10,w={2,2,6,5,4},v={6,3 ...

  8. 进阶实验4-3.5 哈夫曼编码 (30 分)

    仅供参考 #include <iostream> #include <cstdio> #include <queue> #include <string> ...

  9. 哈夫曼编码 译码java_基于Java的哈夫曼编码译码系统_报告毕业论文

    基于Java的哈夫曼编码译码系统_报告毕业论文 1课 程 设 计Java 与面向对象程序设计课程设计基于 Java 的哈夫曼编码译码系统1.问题描述和分工情况1.1 问题描述使用 Java 语言实现哈 ...

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

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

最新文章

  1. swift 语言评价
  2. fluentftp 积极拒绝_【新时代文明实践】光明街道光大社区开展“光盘行动 拒绝浪费 从我做起”新时代文明实践活动...
  3. html如何与py_Web项目如何做单元测试?
  4. Chrome OS 设备或将允许用户自行选择 Linux 发行版
  5. Python协程--生成器(实现多任务)
  6. 运用AARRR模型对App进行系统性的数据分析
  7. 多元线性模型分类变量方差_第三十一讲 R多元线性回归中的多重共线性和方差膨胀因子...
  8. Java多商户商城源码 PC+小程序+APP源码+H5 B2B2C商城源码
  9. python连接ssh_Python建立SSH连接与使用方法
  10. 2021-09-28 网安实验-取证分析-Stuxnet病毒
  11. (附源码)python飞机票销售系统 毕业设计 141432
  12. Ubuntu下解压rar的分卷文件 faster_rcnn_models.part1.rar
  13. 数字电路 时序逻辑电路
  14. Tensorflow学习之tf.keras(一) tf.keras.layers.Model(另附compile,fit)
  15. C#语言实例源码系列-实现屏幕放大器和取色
  16. SRPG游戏开发(五)第三章 绘制地图 - 二 绘制一张简单地图
  17. 老夫带你深度剖析Redisson实现分布式锁的原理
  18. 正弦定理和余弦定理_考查正余弦定理运用,我的班很多同学做不出第2题
  19. IIS 7.5 请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理。
  20. Android 常用开源库总结

热门文章

  1. pix4d操作流程_利用精灵配合PIX4D软件制作正摄图片的简单制作流程
  2. C语言的sqrt函数的调用
  3. 短信验证码和邮箱验证码
  4. 使用python的netCDF4库读取.nc文件 和 创建.nc文件
  5. 如何在csdn写博客
  6. 最速下降法解析(理解笔记)
  7. 37、购物系统需求分析
  8. Origin常见使用问题集锦
  9. matlab编制刚度矩阵,单元刚度矩阵MATLAB编程.docx
  10. 密码学:一文读懂常用加密技术原理及其逻辑与应用方法