[huffman tree] fast_wpl带权路径长度的快速计算

2023-11-20 12:40

本文主要是介绍[huffman tree] fast_wpl带权路径长度的快速计算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

wpl: weighted path length,指带权路径长度。

        要解出一组权值对应huffman树的带权路径长度,最直接的做法是先构造出huffman树,然后计算所有叶子结点的带权路径之和,即:

gif.latex?wpl%28T%29%3D%5C%3B%20%5Csum_%7Bk%7D%5CL_%7Bk%7D*w_%7Bk%7D

        这种解法需要我们先构造出huffman树,然后标记每个叶子结点对应的深度,再遍历所有的叶子节点。

        但实际上,如果只需要求解wpl,我们并不需要构造huffman树,更不需要求解深度,遍历叶子节点。只需要反复对原节点及新生成的节点的最小权值进行反复加和即可。

先给出代码:(默认权值数组有序)

//默认权重数组w已经有序(从小到大)
//指针p指向当前最小权值的index,初始值给1
//n为数组w的规模
//权重数组w默认1为起始位
int ans=0;
int fastwpl(int w[],int p,int n)   
{if(n<=1) return 0;        //没有或只有一个节点,wpl为0;if (p>= n) return ans;    //当p指向最末位(根节点),求解结束else {int new_w = w[p] + w[p+1];  //取出两个最小权值,生成新权值ans += new_w;               //插入新权值节点////查找插入位置int i = p+2;        //由于两个最小权值已取出,所以从p+2开始检索while (new_w > w[i] && i<=n ) i++;//在i之前插入新权值for (int j = p + 1; j < i-1; j++) w[j] = w[j + 1];w[i - 1] = new_w;//指针后移一位(每次运算,删除两个最小节点,生成一个新节点,故p+1)p++;fastwpl(w, p, n);}
}

算法说明(以下图huffman树为例):                 

5af8b3a04d434f03917ae7e0bcfa58df.png

最直接的解法为:

                                        gif.latex?wpl%3D2*3&plus;4*3&plus;5*2&plus;7*1%3D35

本文解法为:

                ​​​​​​​        ​​​​​​​        ​​​​​​​        gif.latex?wpl%3D2&plus;4&plus;5&plus;6&plus;7&plus;11%3D35

即将所有非根节点权重进行加和。

        这个解法看似不可理喻,它好像完全没考虑节点的路径长度。实际上,“路径长度”,即叶子深度的计算被蕴含在对中间节点的反复求和过程中。

如:节点2、4的路径长度为3,即其带权路径长为2*3+4*3,相当于对2和4反复相加了3次。

        换种思路,当我们对由 2 + 4 构成的新节点 6 进行相加时,也相当于对进行了一次+2+4运算。

即+2+4+6=+2+4 +(2+4) = + 2 * 2 + 4 * 2。

        同样,下一层运算,对6 + 5 得到的新节点11进行相加,相当于又对 6 = 2 + 4进行了一次加和。

        因此在对新节点进行不断加和的过程,相当于不停在迭代叶子节点2和4的路径长度。

具有普遍性的,我们可以得出结论:

       wpl=生成huffman树的所有非根节点权值之和

        由此,要计算一组权值的最小加权路径长度,我们只需要不停迭代相加叶子节点及其新生成的权值节点即可。在权值数组有序情况下,复杂度为O(n);

        至于排序,我们可以使用快排或归并排序

 

 

 

这篇关于[huffman tree] fast_wpl带权路径长度的快速计算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/394670

相关文章

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

hdu2544(单源最短路径)

模板题: //题意:求1到n的最短路径,模板题#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#i

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

v0.dev快速开发

探索v0.dev:次世代开发者之利器 今之技艺日新月异,开发者之工具亦随之进步不辍。v0.dev者,新兴之开发者利器也,迅速引起众多开发者之瞩目。本文将引汝探究v0.dev之基本功能与优势,助汝速速上手,提升开发之效率。 何谓v0.dev? v0.dev者,现代化之开发者工具也,旨在简化并加速软件开发之过程。其集多种功能于一体,助开发者高效编写、测试及部署代码。无论汝为前端开发者、后端开发者

POJ1988带权并查集

M u v 将u所在的堆移动到v所在的堆的上面 C u 求u的下面有多少块 带权并查集 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;i