求解电文哈弗曼加权路径大小

# include <iostream>
using namespace std ;
typedef struct
{
 unsigned int weight ; //节点的权值
 unsigned int parent ;
 unsigned int lchild ;
 unsigned int rchild ;
}HTNode,*HuffmanTree;
//typedef char** HuffmanCode ;
void InitHuffmanTree(HuffmanTree & ,int );
void Select(HuffmanTree HT ,int n,int & s1,int & s2);
int Min_Weight(HuffmanTree HT ,int n );
void InitHuffmanTree(HuffmanTree & HT ,int n);
void HuffmanCoding(HuffmanTree & HT , int n);
int Weight_Length(HuffmanTree HT , int n);// 计算带权路径长度
int Find_length(HuffmanTree HT ,int n);// 计算每个叶子节点到根节点的路径长度
int main(void)
{
 int datanum ; // 数据的组数
 scanf ("%d",&datanum);
 while (datanum)
 {
  HuffmanTree HT;
  int n ;  // 每组数据的个数
  scanf("%d",&n);
  InitHuffmanTree(HT,n); // 初始化哈弗曼树为编码做准备
  HuffmanCoding(HT,n);   // 开始编码
  /*for (int i = 1; i <= 2*n-1 ; i ++) // 此处用于查看内存中的值,检查编码是否正确
  {
   printf ("%5d%5d%5d%5d%5d\n",i,HT[i].weight ,HT[i].lchild ,HT[i].rchild ,HT[i].parent);
  }
  */
  printf("%d\n",Weight_Length(HT,n));
  datanum -- ;
 }
 return 0 ;
}
int Weight_Length(HuffmanTree HT , int n)
{
 int len = 0 ;
 while (n)
 {
  len = len + Find_length(HT,n) * HT[n].weight ;
  n -- ;
 }
 return len ;
}
// 因为从根节点到叶子的路径长度不好找,难以确定走的方向,此处才用的是从叶子到根节点走的方式,每走一步记下,更新长度
int Find_length(HuffmanTree HT ,int n)
{
 int distance = 0 ;
 int f ;
 for (f = HT[n].parent ;f != 0 ; f = HT[f].parent)
 {
  distance ++ ;
 }
 return distance ;
}
void HuffmanCoding(HuffmanTree & HT , int n)
{
 int m = 2 * n - 1 ;
 for (int i = n + 1 ; i <= m ; i ++)
 {
  int s1,s2;
  Select(HT,i-1,s1,s2); //  在HT中选择两个权值parent为0的相对较小的元素,返回的值中满足s1>=s2的关系
  HT[s1].parent = i ;
  HT[s2].parent = i ;
  HT[i].lchild = s1 ;
  HT[i].rchild = s2 ;
  HT[i].weight = HT[s1].weight + HT[s2].weight ;
 }
 return ;
}
// 找到两个相对较小的元素并返回
void Select(HuffmanTree HT ,int n,int & s1,int & s2)
{
 s1 = Min_Weight(HT,n);
 s2 = Min_Weight(HT,n);
 return ;
}
int Min_Weight(HuffmanTree HT ,int n )  // 找到相对小的元素并将其标记以表示将其从集合中删去
{
 unsigned int  k = 1000 ;
 unsigned int min = 0  ;
 int i = 1;
 while (i <= n )
 {
  if (!HT[i].parent && HT[i].weight < k)
  {
   k = HT[i].weight  ;
   min = i ;
  }
  i ++ ;
 }
 HT[min].parent = -1 ;  // 标示找到的较小的元素的位置
 return min;
}

void InitHuffmanTree(HuffmanTree & HT ,int n)
{
 int m = 2*n-1;
 HT = (HuffmanTree)malloc( (m+1) * sizeof(HTNode));  // 此处因为不用0号单元所以得多申请一块内存空间
 if (!HT)
 {
  exit(-1);
 }
 for(int i = 1 ; i <= n ; i ++ )
 {
  scanf("%d",&HT[i].weight);
  HT[i].lchild = 0;
  HT[i].parent = 0;
  HT[i].rchild = 0;
 }
 for (i = n + 1 ;i <= m ;i ++)
 {
  HT[i].lchild = 0 ;
  HT[i].parent = 0 ;
  HT[i].rchild = 0 ;
  HT[i].weight = 0 ;
 }
 return ;
}
时间: 2024-07-31 20:15:53

求解电文哈弗曼加权路径大小的相关文章

哈弗曼压缩与解压的原理及对象化实现

这一次主要是跟大家探讨一下哈弗曼压缩的原理及实现,由于过程化的实现更加容易理解也更加直观 ,所以这里首先会分步骤跟大家讲解一下哈弗曼压缩的具体实现方法,然后再与大家分享一下对象化的实 现. 首先,我们要知道文件为什么能压缩? 文件是由字节所组成的,一个字节的长度为8位,所以最多只存在256种字节,而一个文件中一般存在 许多相同的字节,我们把相同的字节以一种更加精简的方式表示,就完成了我们所说的压缩. 哈弗曼压缩的原理是什么? 上次博客中提到了哈弗曼编码,但是只是粗略的带过了,这一次举一个具体的例

哈弗曼树与哈弗曼编码

哈弗曼,一个在几乎所有讲数据结构的书中都有出现过的人物,他的鼎鼎大名想必就不用我多说了. 这一次来给大家讲解一下哈弗曼树的构建与哈弗曼编码的基本原理,有什么用呢?别急,还是先学会创建 一棵哈弗曼树吧. 哈弗曼树又称最优二叉树,最优二叉树就是带权路径长度WPL最小的二叉树,那么我们就得搞清几个概 念: 1. 路径长度:从树中的一个结点到另一个结点之间的分支构成这两个结点的路径,路径上的分支数目 称为路径长度. 2. 树的路径长度:从树根到每一个结点的路径长度之和,我们所说的完全二叉树就是这种路径长

UVa 10954 Add All:哈弗曼树

10954 - Add All Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=1895 Yup!! The problem name reflects your task; just add a set of numbers. But you may fe

绝对路径-求解文件上传的路径问题

问题描述 求解文件上传的路径问题 /// /// 上传文件 /// /// 上传Token /// key /// 本地文件名 public CallRet PutFile(string upToken string localFile string key) { if (!File.Exists(localFile)) { throw new Exception(string.Format(""{0} does not exist"" localFile)); }

java实现哈弗曼编码与反编码实例分享(哈弗曼算法)_java

复制代码 代码如下: //哈弗曼编码的实现类public class HffmanCoding {    private int charsAndWeight[][];// [][0]是 字符,[][1]存放的是字符的权值(次数)    private int hfmcoding[][];// 存放哈弗曼树    private int i = 0;// 循环变量    private String hcs[];    public HffmanCoding(int[][] chars) {  

教你一分钟玩转PS路径描边

  Photoshop的路径工具和钢笔工具,很容易被人忽视,功能很强大,一直很低调.今天咱一块唠唠怎么用路径和钢笔,快速绘制简易线状图标,这个看了都能做噢!!!!哪怕是第一天学PS,也能做到. 有人说UI难学,摸不到门路,那就从这一课开始吧. (心急的同学,直接翻到中下位置,教程部分即可,先练练手) 最终线条图标: 大背景:扁平化下的极简主义 自从苹果家扁平化后,整个世界都扁了.似乎被人们扔了很久的极简主义,一夜之间又流行起来了.看了下面的,是不是很清新,很直接呀.这样的图标适用于底部的标签栏中

c-跪求大神 帮忙,这段关于哈夫曼编码 的程序着实看不懂啊。。。。。。。

问题描述 跪求大神 帮忙,这段关于哈夫曼编码 的程序着实看不懂啊....... struct Codetype{//哈弗曼编码数据类型 char bits;//编码流-数组,n为为哈夫曼树中叶子结点的数目,编码的长度不可能超过n int start;//编码实际在编码流数组里的开始位置 }; Codetype *HuffmanCode(hufmtree *tree){//哈弗曼编码的生成 int i,j,p,k; Codetype *code; if(tree==NULL) return NUL

九度题目1172:哈夫曼树

题目1172:哈夫曼树 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4366 解决:1827 题目描述: 哈夫曼树,第一行输入一个数n,表示叶结点的个数.需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题 目需要输出所有结点的值与权值的乘积之和. 输入: 输入有多组数据. 每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000). 输出: 输出权值. 样例输入: 5  1 2 2 5 9 样例输出: 37 来源:

java一些常用代码的分享!

问题描述 java访问xml文件importjava.io.*;importjavax.xml.parsers.DocumentBuilder;importjavax.xml.parsers.DocumentBuilderFactory;importorg.w3c.dom.Document;importorg.w3c.dom.Element;importorg.w3c.dom.Node;importorg.w3c.dom.NodeList;publicclassxmljava{publicsta