数据结构大作业–哈夫曼树的应用
题目一:
1、哈夫曼树
请为下面这段英文文本构造哈夫曼编码:
“Effificient and robust facial landmark localisation is crucial for the deployment of
real-time face analysis systems. This paper presents a new loss function, namely
Rectifified Wing (RWing) loss, for regression-based facial landmark localisation with
Convolutional Neural Networks (CNNs). We fifirst systemically analyse different loss
functions, including L2, L1 and smooth L1. The analysis suggests that the training of
a network should pay more attention to small-medium errors. Motivated by this
finding, we design a piece-wise loss that amplififies the impact of the samples with
small-medium errors. Besides, we rectify the loss function for very small errors to
mitigate the impact of inaccuracy of manual annotation” 要求如下:
- 请计算出每个字符出现的概率,并以概率为权重来构造哈夫曼树,写出构造
过程、画出 最终的哈夫曼树,得到每个字符的哈夫曼编码。 - 请将上述设计哈夫曼编码的过程,用代码来实现,并输出各个字母的哈夫曼
编码。(有代码,有运行结果的截图) - 请分析算法的效率,至少包括时间复杂度和空间复杂度等。
一、题目分析
1)
报文由262个字符组成,所以报文字符总数为262(大概?太难数了),报文字符的种类有39种,用词频代替频率(一样的,词频高=频率高,频率中有小数不好算)每种字符的词频如图1所示:
2)
构造过程:
1.根据给定的n个词频{w1,w2,…,.wn}构成n棵二叉树的集合F={T1,T2,…,Tn},其中每棵二叉树Ti 中只有一个带权为wi根结点,其左右子树均为空。
2.在F中选取两棵根结点的词频最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的词频为其左右子树上根结点的词频之和。
3.在F中删除这两棵树,同时将新得到二叉树加入F中。
4.重复2和3步骤,直到F只含一棵树为止。如图2所示这棵树便是哈夫曼树。
由哈夫曼树可知:
字符 ’ ’ 的编码是 101
字符 ‘(’ 的编码是 00100100
字符 ‘)’ 的编码是 00100101
字符 ‘,’ 的编码是 0111100
字符 ‘-’ 的编码是 0110010
字符 ‘.’ 的编码是 0110011
字符 ‘1’ 的编码是 00100110
字符 ‘2’ 的编码是 001010100
字符 ‘B’ 的编码是 001010101
字符 ‘C’ 的编码是 00100111
字符 ‘E’ 的编码是 001010110
字符 ‘L’ 的编码是 01111010
字符 ‘M’ 的编码是 001010111
字符 ‘N’ 的编码是 0010000
字符 ‘R’ 的编码是 00101000
字符 ‘T’ 的编码是 00101001
字符 ‘W’ 的编码是 01111011
字符 ‘a’ 的编码是 1001
字符 ‘b’ 的编码是 11101100
字符 ‘c’ 的编码是 01101
字符 ‘d’ 的编码是 00011
字符 ‘e’ 的编码是 1101
字符 ‘f’ 的编码是 11100
字符 ‘g’ 的编码是 001011
字符 ‘h’ 的编码是 00010
字符 ‘i’ 的编码是 1111
字符 ‘k’ 的编码是 0010001
字符 ‘l’ 的编码是 0011
字符 ‘m’ 的编码是 01110
字符 ‘n’ 的编码是 0100
字符 ‘o’ 的编码是 0101
字符 ‘p’ 的编码是 011000
字符 ‘r’ 的编码是 0000
字符 ‘s’ 的编码是 1100
字符 ‘t’ 的编码是 1000
字符 ‘u’ 的编码是 111010
字符 ‘v’ 的编码是 11101101
字符 ‘w’ 的编码是 1110111
字符 ‘y’ 的编码是 011111
二、代码编写
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int num[N], c[N], n;
char s[N];
/*
* num[i]表示ASCII码为i的字符出现的频率
* c[i]表示所有词频不为0的字符中ascii码从小到大第i个的词频
* n表示词频不为0的字符个数
* s表示输入的文本串
*/
string str = "", ss[N];
/*
* str表示原文去重并且按照ASCII码排序之后的字符串,下标从0开始
* ss[i]表示str[i]的哈夫曼编码
*/
struct node {
int l;//左儿子
int r