最优二叉树

最优二叉树&&哈夫曼编码

大憨熊 提交于 2019-12-20 18:06:52
树的路径长度 树的路径长度是从树根到树中每一结点的路径长度之和。在结点数目相同的二叉树中,完全二叉树的路径长度最短。 树的带权路径长度(weighted path length of tree,wpl) 结点的权值:在一些应用中,赋予树中结点的一个有某种意义的实数、 结点的带权路径长度:结点到树根之间的路径长度与该结点上权的乘积 树的带权路径长度(wpl):定义为树中所有结点的带权路径长度之和 最优二叉树 在权为w1,w2,...,wn的n个 叶子结点 所构成的所有二叉树中,带权路径长度最小(即代价最小)的二叉树成为最优二叉树。 注意: 叶子上的权值均相同时,完全二叉树一定是最优二叉树,否则完全二叉树不一定是最优二叉树。 最优二叉树中,权值越大的叶子结点离根越近 最优二叉树的形态不唯一,wpl最小 构造最优二叉树 哈夫曼算法 根据给定的n个权值w1,w2,...,wn构成n棵二叉树的森林F={T1,T2,..,Tn},其中每棵二叉树Ti中只有一个权值为wi的根节点,其左右子树均为空。 在森林F中选出两棵根结点权值最小的树(当这种的树不止两棵时,可以从中任选两棵),将这两棵树和并称一棵新树,为了保证新树仍是二叉树,需要增加一个新结点作为新树的根,并将所选的两棵树根分别作为新树的左右孩子,将这两个孩子的权值之和作为新树根的权值 对新的森林F重复2,直到森林F只剩一棵树为止。 注意

哈夫曼树与哈夫曼编码

不羁岁月 提交于 2019-12-19 12:39:41
在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN) 树和哈夫曼编码。哈夫曼编码是哈夫曼树的一个应用。哈夫曼编码应用广泛,如 JPEG中就应用了哈夫曼编码。 首先介绍什么是哈夫曼树。哈夫曼树又称最优二叉树, 是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点 的权值乘上其到根结点的 路径长度(若根结点为0层,叶结点到根结点的路径长度 为叶结点的层数)。树的带权路径长度记为WPL= (W1*L1+W2*L2+W3*L3+...+Wn*Ln) ,N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径 长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。 哈夫曼编码步骤: 一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F= {T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算 法,一般还要求以Ti的权值Wi的升序排列。) 二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。 三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。 四、重复二和三两步

Huffman编码

半腔热情 提交于 2019-12-05 15:49:47
n 0 个带权叶子结点所构成的所有二叉树中,带权路径长度WPL最小的二叉树称为Huffman Tree或最优二叉树。 编码:深林中选取两棵结点的权值最小的子树分别作为左右子树构造一棵新的二叉树。 typedef struct { char ch; unsigned int weight; unsigned int parent, lchild, rchild; }HTNode,*HuffmanTree; typedef char** HuffmanCode;   编码 void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, int n, int* w,char *chars) { int s1, s2; HTNode *p ; int i; int m = 2 * n - 1; HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); for (p = HT+1, i = 1; i <= n; i++, p++, w++,chars++) { p->ch = *chars; p->weight = *w; p->parent = p->lchild = p->rchild = 0; } for (; i <= m; i++, p++) { p->ch='\0'; p->weight =

哈弗曼树(最优二叉树)

自闭症网瘾萝莉.ら 提交于 2019-12-05 09:08:04
主要摘自https://www.cnblogs.com/skywang12345/p/3706821.html感谢大佬 https://www.cnblogs.com/kubixuesheng/p/4397798.html这位大佬举例很好 一、哈夫曼树(霍夫曼树) 注. 哈夫曼树也称最优二叉树。  叶子节点的权值 是对叶子节点赋予的一个有意义的数值量。  设二叉树具有 n 个带权值的叶子结点,从根节点到各个叶子结点的路径长度与相应叶子结点权值的乘积之和叫做 二叉树的带权路径长度。   给定一组具有确定权值的叶子结点,可以构造处不同的二叉树,将其中带权路径长度最小的二叉树称为 哈夫曼树 。、 定义 :给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树。 这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树 初始化 :由给定的 n 个权值 { ω 1 , ω 2 , ⋯ , ω n } {ω1,ω2,⋯,ωn}构造 n 棵只有一个根节点的二叉树,从而得到一个二叉树集合 F = { T 1 , T 2 , ⋯ , T n } F={T1,T2,⋯,Tn}。 选取与合并: 在 F F中选取根节点的权值最小的两颗二叉树分别作为左右子树构造一棵新的二叉树(一般情况下将 权值大的结点作为右子树 。),这棵新二叉树的根节点的权值为其左

树的数据结构

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

题解 P1040 【加分二叉树】

↘锁芯ラ 提交于 2019-11-28 21:47:43
思路: 以中序遍历的方式输入结点上的值,由于我们需要以前序遍历的方式输出结点, 所以我们必须要知道根结点 我们要确定最大根结点就必须求出最大权值树,我们枚举所有结点作为根结点 如果根结点的编号为x,那么左子树的结点有1~x-1,右子树 结点有x+1~n 代码: #include<bits/stdc++.h> using namespace std; const int N=35; int tree[N]; //用于存储结点的值 int value[N][N]; //用于存储最大权值和 int root[N][N]; //存储根结点 int dfs(int l,int r) { if(l>r) //空子树,规定其加分为1 return 1; if(l==r) //叶子结点,直接返回该结点的值,且将其记录为根 { root[l][r]=l; return tree[l]; } /* 在每一次搜索的开始,如果已经做过,直接调用答案,回溯 */ if(value[l][r]) //记忆化搜索 防止重复计算 return value[l][r]; // int ans=0,flag; for(int i=l;i<=r;i++) //枚举子层次根结点 { int sum=dfs(l,i-1)*dfs(i+1,r)+tree[i]; if(sum>value[l][r]) { value[l]

近千道真题面经汇总(内附薪资)

我与影子孤独终老i 提交于 2019-11-26 13:00:51
前言 感谢ShawnNg的投稿。 原文开始 我成功拿到了心仪的offer(自然语言算法工程师),也感觉各位大佬分享的面经,所以想回馈一波。在这期间我找到很多面经资料,自己用代码过滤整理了出来。我个人觉得这个资料是十分有用的,我希望也能帮助到各位。祝大家也能够早日找到心仪的工作! [图片上传中…(image-4c2d62-1510246116379-17)] 目录 HR常问问题 开放题 机器学习 编程题 HR常问问题 为什么不读博、对读博报以什么态度。 HR常问问题 为什么选择百度,谷歌百度都给你offer你选哪个。 为什么选择跨专业学计算机? 为什么选择阿里 以后可能要学习很多新技术,你怎么看。 你平时喜欢做什么?看过哪些书?最近在看什么书? 你觉得最有挑战的项目是什么。 你觉得最难忘的事情是什么? 你认为你的优(缺)点是什么。 你还有什么想问的? 加班怎么看。 印象最深刻的事? 压力最大的情况是什么时候。 在面试过程中觉得自己那些当面有进步 场景分析题,有一个任务给你,要求一个月完成,但是以目前的能力一个月完成不了,现在你知道有一个同事擅长这部分工作,但是他有自己的活,帮助你就可能耽误他的进度,问你咋办。 大学令你觉得最不爽的事情是什么 如何学习的? 如何看待加班。 实习期间项目,在组内担任的角色,是否熟悉其他组员的工作。 家庭教育观念? 家里什么情况?独生子女? 将来的职业规划

Huffman编码

怎甘沉沦 提交于 2019-11-26 01:41:20
n 0 个带权叶子结点所构成的所有二叉树中,带权路径长度WPL最小的二叉树称为Huffman Tree或最优二叉树。 编码:深林中选取两棵结点的权值最小的子树分别作为左右子树构造一棵新的二叉树。 typedef struct { char ch; unsigned int weight; unsigned int parent, lchild, rchild; }HTNode,*HuffmanTree; typedef char** HuffmanCode;   编码 void HuffmanCoding(HuffmanTree& HT, HuffmanCode& HC, int n, int* w,char *chars) { int s1, s2; HTNode *p ; int i; int m = 2 * n - 1; HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); for (p = HT+1, i = 1; i <= n; i++, p++, w++,chars++) { p->ch = *chars; p->weight = *w; p->parent = p->lchild = p->rchild = 0; } for (; i <= m; i++, p++) { p->ch='\0'; p->weight =