哈夫曼树

关于【哈夫曼树】

為{幸葍}努か 提交于 2020-03-19 12:39:43
  为了方便快捷高效率的求得集合中权值最小的2个元素,我采用堆数据结构,它可以以O(logn)的复杂度取得n个元素中的最小值。为了绕过对堆的实现,我采用标准模板库中的相应标准模板——优先队列。 利用语句: priority_queue<int> Q;   建立一个保存元素为int的堆Q,但是此时建立的堆默认是大顶堆,即每次取到的元素是整个堆中的最大元素,于是采用如下语句定义一个小顶堆: priority_queue<int,vector<int>,greater<int> >Q; 关于堆的有关操作如下: Q.push(x); 将元素x放入堆Q中。 int a=Q.top(); 取出堆顶元素,即最小的元素保存在a中。 Q.pop(); 弹出堆顶元素,弹出后堆会自动调整为一个新的小顶堆。 题目1172:哈夫曼树 题目描述: 哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。 输入: 输入有多组数据。 每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。 输出: 输出权值。 样例输入: 5 1 2 2 5 9 样例输出: 37代码如下: #include <iostream> #include <queue> using

哈夫曼树应用——九度OJ题目1107:搬水果

巧了我就是萌 提交于 2020-03-19 08:42:55
哈夫曼算法 1、将所有结点放入集合K。 2、若集合K中剩余结点大于2个,则取出其中权值最小的两个结点,构造他们同时为某个新节点的左右儿子,该新节点是他们共同的双亲结点,设定它的权值为其两个儿子结点的权值和。并将该父亲结点放入集合K。重复步骤2或3。 3、若集合K中仅剩余一个结点,该结点即为构造出的哈夫曼树数的根结点,所有构造得到的中间结点(即哈夫曼树上非叶子结点)的权值和即为该哈夫曼树的带权路径和。 注:使用STL中的优先队列priority_queue可以很容易地实现哈夫曼树,详情见例题。 题目1107:搬水果 题目描述: 在一个果园里,小明已经将所有的水果打了下来,并按水果的不同种类分成了若干堆,小明决定把所有的水果合成一堆。每一次合并,小明可以把两堆水果合并到一起,消耗的体力等于两堆水果的重量之和。当然经过 n‐1 次合并之后,就变成一堆了。小明在合并水果时总共消耗的体力等于每次合并所耗体力之和。 假定每个水果重量都为 1,并且已知水果的种类数和每种水果的数目,你的任务是设计出合并的次序方案,使小明耗费的体力最少,并输出这个最小的体力耗费值。例如有 3 种水果,数目依次为 1,2,9。可以先将 1,2 堆合并,新堆数目为3,耗费体力为 3。然后将新堆与原先的第三堆合并得到新的堆,耗费体力为 12。所以小明总共耗费体力=3+12=15,可以证明 15 为最小的体力耗费值。 输入

哈夫曼树的长度

ε祈祈猫儿з 提交于 2020-03-12 13:57:06
哈夫曼树的长度 哈夫曼树也称最优二叉树,最优指的是其带权路径和最小,而哈夫曼树的长度也指的是其带权路径和。 一般而言,求其长度时,应当将其按照构造的方式进行构造之后,计算每个叶节点的值乘以权重之后的和。 在这个图中,绿色的节点即叶子节点,故此树的长度WPL为 W P L = 1 × 3 + 2 × 3 + 3 × 2 + 3 × 2 + 4 × 2 = 29 WPL = 1\times 3 + 2 \times 3 + 3\times 2+3\times 2 + 4\times 2 = 29 W P L = 1 × 3 + 2 × 3 + 3 × 2 + 3 × 2 + 4 × 2 = 2 9 当然,这样一来,代码的实现难度就很大了,不但要构造哈夫曼树(自下而上),而且要再重新确定叶节点的路径(自上而下)。 另一种思路,利用其特性解决。 先说结论: 带权路径和WPL值等于非叶子节点的值的和。 在此图中树的长度WPL为: W P L = 3 + 6 + 13 + 7 = 29 WPL = 3+6+13+7=29 W P L = 3 + 6 + 1 3 + 7 = 2 9 是不是方便许多? 以下是个人的理解,并非严谨推导。 以叶节点A举例,按公式(1)的计算方式中,A乘以了2,也可以理解为A被加了两次。第一次的值加在其父节点7上,第二次值加在根节点13上。而用公式(2)计算的过程

树与二叉树 | 哈夫曼树

半世苍凉 提交于 2020-03-12 04:43:33
哈夫曼树定义 (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* 80 + 3* 20 + 3* 10 = 100 + 160 + 60 + 30 = 350。 哈夫曼树 哈夫曼树又称最优二叉树。它是 n 个带权叶子结点构成的所有二叉树中,带权路径长度 WPL 最小的二叉树。 哈夫曼树的构造过程: 给定的n个权值{W1,W2,…,Wn}构造n棵只有一个叶结点的二叉树,从而得到一个二叉树的集合F={T1,T2,…,Tn}。 在F中选取根结点的权值最小和次小的两棵二叉树作为左、右子树构造一棵新的二叉树

【牛客网】哈夫曼树

左心房为你撑大大i 提交于 2020-03-10 06:32:52
题目描述 哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。 输入描述: 输入有多组数据。 每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。 输出描述: 输出权值。 示例1 输入 5 1 2 2 5 9 输出 37 备注 原本想优化一下答案,但是耗时没什么改变… 解答1 import java . util . Arrays ; import java . util . Scanner ; public class Test { public static void main ( String [ ] args ) { Scanner scanner = new Scanner ( System . in ) ; while ( scanner . hasNext ( ) ) { int n = scanner . nextInt ( ) , sum = 0 ; int [ ] nums = new int [ n ] ; for ( int i = 0 ; i < n ; i ++ ) { nums [ i ] = scanner . nextInt ( ) ; } for ( int i = 0 ; i < n -

王道计算机机试练习——哈夫曼树

筅森魡賤 提交于 2020-03-09 15:06:41
王道计算机机试——哈夫曼树 题目描述 哈夫曼树,第一行输入一个数 n,表示叶结点的个数。需要用这些叶结点生 成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即 weight,题目需要输出 所有结点的值与权值的乘积之和。 1. 哈夫曼树求法 1)将所有结点放入集合 K。 2)若集合 K 中剩余结点大于 2 个,则取出其中权值最小的两个结点, 构造他 们同时为某个新节点的左右儿子,该新节点是他们共同的双亲结点,设定它的权 值为其两个儿子结点的权值和。并将该父亲结点放入集合 K。重复步骤 2 或 3。 3)若集合 K 中仅剩余一个结点, 该结点即为构造出的哈夫曼树数的根结点, 所有构造得到的中间结点 (即哈夫曼树上非叶子结点 )的权值和即为该哈夫曼树 的带权路径和。 为了方便快捷高效率的求得集合 K 中权值最小的两个元素,我们需要使用堆数 据结构。它可以以 O(logn)的复杂度取得 n 个元素中的最小元素。为了绕过对 堆的实现,我们使用标准模板库中的相应的标准模板 ——优先队列。 2.大顶堆与小顶堆 priority_queue < int > Q ; 建立一个保存元素为 int 的堆 Q,但是请特别注意这样建立的堆其默认为大 顶堆,即我们从堆顶取得的元素为整个堆中最大的元素。而在求哈夫曼树中,我 们恰恰需要取得堆中最小的元素,于是我们使用如下语句定义一个小顶堆: priority

实现哈夫曼树(最优二叉树)

余生长醉 提交于 2020-03-05 18:39:13
public class HuffmanTree { //节点 public static class Node<E> { E data; //数据 int weight; //权重 Node leftChild; //左子节点 Node rightChild;//右子节点 public Node(E data, int weight) { super(); this.data = data; this.weight = weight; } public String toString() { return "Node[" + weight + ",data=" + data + "]"; } } public static void main(String[] args) { List<Node> nodes = new ArrayList<Node>(); //把节点加入至list中 nodes.add(new Node("a", 10)); nodes.add(new Node("b", 15)); nodes.add(new Node("c", 12)); nodes.add(new Node("d", 3)); nodes.add(new Node("e", 4)); nodes.add(new Node("f", 13)); nodes.add(new Node("g"

哈夫曼树

一个人想着一个人 提交于 2020-03-03 19:38:06
求WPL的代码(不用建树),给定n个叶子节点。 时间复杂度 \(O(n\log n)\) #include<bits/stdc++.h> using namespace std; typedef long long ll; #define rint register int #define il inline inline int rd(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); return x*f; } struct node { int val,h; friend bool operator < (node a,node b) { return a.val!=b.val?a.val>b.val:a.h>b.h; } }; priority_queue<node>q; const int N=505; int n,ans; int main() { n=rd(); for(rint i=1;i<=n;++i) q.push(node{rd(),1}); for(rint i=1;i<n;++i) { int tmp=0,mx=0

北京邮电大学复试机试(2)

回眸只為那壹抹淺笑 提交于 2020-02-22 14:02:02
题目描述 哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。 输入描述: 输入有多组数据。 每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。 输出描述: 输出权值。 示例1 输入 5 1 2 2 5 9 输出 37 思路: 本体实际就是求带权路径长度 import java . util . * ; class Tree { int data ; Tree left ; Tree right ; Tree ( int data ) { this . data = data ; } } public class Main { public static void main ( String [ ] args ) { Scanner input = new Scanner ( System . in ) ; int n = input . nextInt ( ) ; List < Tree > treeList = new ArrayList < Tree > ( ) ; //构建N棵只有一个根节点的树 for ( int i = 0 ; i < n ; i ++ ) { treeList . add ( new Tree

哈夫曼树与带权路径长度

爷,独闯天下 提交于 2020-02-19 04:05:11
哈夫曼树与带权路径长度 问题: 权值分别为从19,21,2,3,6,7,10,32的结点,构造一棵哈夫曼树,该树的带权路径长度是? 构建哈夫曼树: 1.从19,21,2,3,6,7,10,32之中选取连个最小的2,3。 2.从19,21,5,6,7,10,32之中选取连个最小的5、6。 3.从19,21,11,7,10,32之中选取连个最小的7、10。 4.从19,21,11,17,32之中选取连个最小的11、17。 5.从19,21,28,32之中选取连个最小的19、21。 6.从40,28,32之中选取连个最小的28、32。 7.最后,哈夫曼树建成。 8.计算带权路径长度: 结点的带权路径长度=从根结点到该结点之间的路径长度 X 该结点的权。 来源: CSDN 作者: xwq9797 链接: https://blog.csdn.net/qq_35456686/article/details/104376041