哈夫曼树

数据结构-哈夫曼树(Huffman)

匿名 (未验证) 提交于 2019-12-03 00:43:02
哈夫曼树 哈夫曼树概述 (1)总括: 哈夫曼(Huffman)树又称为 最优二叉树 ,是一类 带权路径长度 最短 的树 (2)树的路径长度: 树根到每个结点的路径长度 之和 (对于 节点个数相同 的二叉树来说, 路径长度最短树是完全二叉树 ) (3)权值( Weight ): 每个叶子结点所赋予的特殊值 (4)叶子带权路径长度: 一个叶子结点的权值 与 该结点到根的路径长度 的 乘积 (5)二叉树的带权路径长度( Weighted Path Length ): 简记 WPL , 所有 叶子带权路径长度之和 WPL= (w是第k个叶子结点的权值,l为第k个叶子结点的路径长度) 给定n个叶子结点,在这些结点构造的二叉树中, WPL最小 的二叉树称为哈夫曼树 哈夫曼树的构造 (1)思路: 必须使权值相对大的叶子结点更靠近根结点 。 (2)哈夫曼算法: 左右孩子都为空 (说白了就是哈夫曼树的原始叶子节点) 选取两棵根节点最小的树 作为左右子树构造一棵新的二叉树,并且该二叉树的根节点权值为左右子树根结点权值之和 删除这两棵被结合的二叉树 ,同时 新的二叉树加入F 重复b c ,直到F中 只剩下一棵二叉树 ,这棵二叉树就是哈夫曼树 (3)总结下规律 成为哈夫曼树的叶子结点 ,所以: 原始二叉树数n=哈夫曼树叶子结点数 共结合n-1次 ,每次结合新形成一个结点 具有n个叶子结点的哈夫曼树 具有n

【哈夫曼树】4080:Huffman编码树

匿名 (未验证) 提交于 2019-12-03 00:27:02
4080:Huffman编码树 1000ms 65536kB 描述 构造一个具有n个外部节点的扩充二叉树,每个外部节点Ki有一个Wi对应,作为该外部节点的权。使得这个扩充二叉树的叶节点带权外部路径长度总和最小: Wi:每个节点的权值。 Li:根节点到第i个外部叶子节点的距离。 编程计算最小外部路径长度总和。 输入 第一行输入一个整数n,外部节点的个数。第二行输入n个整数,代表各个外部节点的权值。 2<=N<=100 输出 输出最小外部路径长度总和。 样例输入 41 1 3 5 样例输出 17 哈夫曼树类题目比较单一,套模板即可。 #include<iostream> #include<stdio.h> #include<queue> using namespace std; int n,t; int main(){ cin>>n; priority_queue<int,vector<int>,greater<int> >Q; for(int i=0;i<n;i++){ cin>>t; Q.push(t); } int ans=0; int a,b; while(Q.size()>1){ a=Q.top(); Q.pop(); b=Q.top(); Q.pop(); ans=ans+a+b; Q.push(a+b); } cout<<ans<<endl; } 文章来源: 【哈夫曼树

构建哈夫曼树,并输出哈夫曼编码

匿名 (未验证) 提交于 2019-12-03 00:26:01
输入条件:输入从小到大排列的n个正整数,作为叶子的权值,共同完成构建具有n片叶的,根指针为Hroot的哈夫曼树 (1)程序前部的定义 #include <stdio.h> #include <mm_malloc.h> #include <string.h> #define MAX 999 //监督元 #define n 6 //n个叶子节点 char s[6]={0}; //存放哈夫曼编码的数组,初始化 typedef struct Hfnode { int data; //权值 char hfcode[6]; //哈夫曼编码 struct Hfnode *Lson,*Rson,*next; }Hfnode,*Hfptr; (2)主控函数 //主控函数 int main() { int l; Hfptr Hfroot,head; head=inition(); //调用初始化函数 Hfroot=creatHftree(head);//调用造树函数 l=Hfcode(Hfroot,0,0);//输出哈夫曼编码 return 0; } (3)初始化函数 //初始化函数 Hfptr inition() { int i;Hfptr h,p; h=p=(Hfptr)malloc(sizeof(Hfnode)); h->data=MAX; for(i=1;i<=n;i++) { p->next

哈夫曼树编码译码

匿名 (未验证) 提交于 2019-12-03 00:09:02
一:问题描述 【问题描述】 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编/译码系统。 【任务要求】 一个完整的系统应具有以下功能: 1) I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。 2) E:编码(Encoding)。利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。 3) D:译码(Decoding)。利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。 【测试数据】 用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码:“THIS PROGRAM IS MY FAVORITE”。 字符 A B C D E F G H I J K L M 频度 186 64 13 22 32 103 21 15 47 57 1 5 32 20 字符 N O P Q R S T U V W X Y Z 频度

数据结构--哈夫曼树

匿名 (未验证) 提交于 2019-12-02 23:56:01
Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树。 定义 :给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。 这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答。 (01) 路径和路径长度 定义 :在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。 例子 :100和80的路径长度是1,50和30的路径长度是2,20和10的路径长度是3。 (02) 结点的权及带权路径长度 定义 :若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。 例子 :节点20的路径长度是3,它的带权路径长度= 路径长度 * 权 = 3 * 20 = 60。 (03) 树的带权路径长度 定义 :树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。 例子 :示例中,树的WPL= 1* 100 + 2*5 0 + 3* 20 + 3* 10 = 100 + 100 + 60 + 30 =290。 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支构成这两个结点之间的路径。 ② 路径长度

哈夫曼树的创建及编码

匿名 (未验证) 提交于 2019-12-02 22:56:40
哈夫曼树编码:从根节点开始,按左子树为'0',右子树为'1'编码,最后找到叶子节点的编码 #include <stdio.h> #include <malloc.h> #include <conio.h> #include <string.h> #include <iostream> using namespace std; #define MAX_LENGTH 100//叶子节点的最大数量 typedef char **HuffmanCode; typedef struct HTNode{ unsigned int weight;//该节点所占的权重 unsigned int parent,lchild,rchild;// 该节点的父节点,左孩子,右孩子 HTNode(unsigned int a,unsigned int b,unsigned int c,unsigned int d){ weight=a,parent=b,lchild=c,rchild=d; } }HTNode,*HuffmanTree; void Select(HuffmanTree HT,int i,int &s1,int &s2){//把没有父节点的所有节点中最小的两个值赋值给s1,s2 int j,k = 1; while(HT[k].parent) //找最小的父节点为0,即没有父节点的点 k++;

002-词向量,神经网络模型,CBOW,哈夫曼树,Negative Sampling

匿名 (未验证) 提交于 2019-12-02 22:56:40
词向量: 无论是一段话或是一篇文章,词都是最基本的组成单位。 如何让计算机利用这些词? 重点是如何把一个词转换成一个想向量 如果在一个二维空间中,had,has,have意思相同,所以要离的比较近。 need,help也是离的比较近 要表现出相同,相关。 比如说下面的例子: 哪些词离青蛙frog比较近?同义词 对于两种不同语言,建模之后语言空间也是很接近的, 所以可以说构建出来的词向量跟语言类别无关,只是根据语义环(上下文的逻辑)境来建模。 神经网络模型: 将输入词向量进行首尾相接(projection Layer 投影层),在传给神经网络进行参数优化, 这里的输入向量也需要被优化。 训练样本: 包括前n-1个词分别的向量,假定每个词向量大小m 投影层:(n-1)*m 首尾拼接起来的大向量 输出: 表示上下文为 时,下一个词恰好为词典中第i个词的概率 归一化: 目的就是要求出每一个词的词向量是什么。 神经网络的优势: S1 = ‘’我今天去网咖’’ 出现了1000次 S2 = ‘’我今天去网吧’’ 出现了10次 对于N-gram模型:P(S1) >> P(S2) 而神经网络模型计算的P(S1) ≈ P(S2) 神经网络看来,类似的句子和词都是一个东西 只要语料库中出现其中一个, 其他句子的概率也会相应的增大 skip-gram:根据当前词得到上下文。 CBOW: CBOW

【Java】实现哈夫曼树

匿名 (未验证) 提交于 2019-12-02 21:35:18
哈夫曼树 一种二叉树结构,又称最优树,是带权路径最小的树,通常用于哈夫曼编码中。 压缩的思路是统计出字符的使用频率并加以记录, 根据频率从高到低赋予它们从短到长的编码,以此来提高无损压缩率。 下面我们介绍一下哈夫曼树中的基本概念,然后用一个英语文本来构建哈夫曼树。 基本概念 节点 父节点与子节点:它们是相对的概念,一个父节点会有两个子节点,父节点的权为两个子节点之和。 左节点与右节点:根据两个子节点的位置命名。 根节点:最上层的节点,有且只有一个。 叶子节点:最下层的节点,原始数据。 哈夫曼编码 从根节点向下计算,左节点为0,右节点为1。 路径 路径:每个节点之间的通路称之为路径。 路径长度: 路径中分支的数目(生成两个节点为一次)称为路径长度, 从根节点算第一层到第L层之间的路径长度就是L-1,如上图路径长度为2。 Ȩ (一般节点分为存储域及权及哈夫曼编码,储存域用于存储数据) 结点的权:一个有着某种含义的数值(比如出现频率),则这个数值称为该结点的权。 带权路径长度为:从 根结点到该结点 之间的路径长度与 该结点的权 的乘积。 树的带权路径长度:所有叶子结点的带权路径长度之和,记为WPL。 (被称为最优树的原因:按照该方法构建的二叉树WPL最小) 构建方法 *提前准备: 我们需要一组按序排列的数(如:5,9,12,32,45,55) *构建顺序: 从下到上

浅谈Huffman树

陌路散爱 提交于 2019-12-02 15:14:05
学习ing 二叉哈夫曼树 一、定义 给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是 带权路径长度最短 的树,权值较大的结点离根较近。(摘自百度百科) 带权路径:到达该叶子节点经过的边数×叶子节点当前代表的数 二、实现 贪心 每次从所给序列中找到两个权值最小的点合并,将合并后的新权值放回序列中,然后反复操作,直到序列中只剩下一个元素。(用堆实现) 三、正确性 因为每次都选择的是权值最小的点先合并,最后构成的一个树中这些点一定是位于树中深度最大的地方。 四、性质 按照这个方法构造出来的哈夫曼树满足每个编码都不会是其他编码的左起子串(可以理解为前缀) 因为从根到该叶子结点构成一个编码,中途不会存在其他编码 例题:NOIP 2004 合并果子 k叉哈夫曼树 一、定义 和二叉哈夫曼树没什么区别。 二、实现 1.将二叉哈夫曼树中每次选两个值最小的,改为每次选前k个最小的即可 2.只有满的k叉哈夫曼树构造出来才是最优的。不满足的,就补充0构造为满的k叉哈夫曼树。 若序列中有n个数,现在要求构造k叉哈夫曼树,如果满足 ( n − 1 ) % ( k − 1 ) = = 0 (n-1)\%(k-1)==0 ( n − 1 ) % ( k − 1 ) = = 0 则为满的 (因为每取k个出来

树的数据结构

荒凉一梦 提交于 2019-12-02 02:41:01
树、森林与二叉树的转换 1、树转换为二叉树 由于二叉树是有序的,为了避免混淆,对于无序树,我们约定树中的每个结点的孩子结点按从左到右的顺序进行编号。 将树转换成二叉树的步骤是: (1)加线。就是在所有兄弟结点之间加一条连线; (2)抹线。就是对树中的每个结点,只保留他与第一个孩子结点之间的连线,删除它与其它孩子结点之间的连线; (3)旋转。就是以树的根结点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明。 2、森林转换为二叉树 森林是由若干棵树组成,可以将森林中的每棵树的根结点看作是兄弟,由于每棵树都可以转换为二叉树,所以森林也可以转换为二叉树。 将森林转换为二叉树的步骤是: (1)先把每棵树转换为二叉树; (2)第一棵二叉树不动,从第二棵二叉树开始, 依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子结点,用线连接起来。 当所有的二叉树连接起来后得到的二叉树就是由森林转换得到的二叉树。 3、二叉树转换为树 二叉树转换为树是树转换为二叉树的逆过程,其步骤是: (1)若某结点的左孩子结点存在,将左孩子结点的右孩子结点、右孩子结点的右孩子结点……都作为该结点的孩子结点, 将该结点与这些右孩子结点用线连接起来 ; (2)删除原二叉树中所有结点与其右孩子结点的连线; (3)整理(1)和(2)两步得到的树,使之结构层次分明。 什么是哈夫曼树?(最优二叉树) 一. 目的