赫夫曼树:

假设有n个权值{w1,w2,w3....},试构造一棵具有 n个叶子节点的二叉树,每个叶子节点带权为wi,则其中 带权路径长度最小的二叉树称为最优二叉树或者叫赫夫曼树
构造赫夫曼树:
假设有n个权值,则构造出的赫夫曼树有n个叶子节点,n个权值分别设置为w1,w2,....wn,则赫夫曼树的构造规则为:
1.将w1,w2...看成是有n棵树的森林;
2.在森林中选择两个根节点的权值最小的树合并,作为一棵新树的左右子树,且新树的根节点权值为其左右子树根节点权值之和;
3.从森林中删除选取的两棵树,并将新树加入森林;
4.重复2、3步,直到森林中只剩一棵树为止,该树即为所求得的赫夫曼树。
实现:
以数组形式存储赫夫曼树节点,节点形态:

/**************************************************
构造赫夫曼树
by Rowandjj
2014/6/2
**************************************************/
#include<IOSTREAM>
using namespace std;#define UINT_MAX 0xfffffffftypedef struct _BITREE_//二叉树
{int data;//存放节点的圈中struct _BITREE_ *lChild;struct _BITREE_ *rChild;
}Bitree,*pBitree;typedef struct _HUFFMANTREE_//赫夫曼树
{unsigned int weight;unsigned int parent;unsigned int lChild;unsigned int rChild;
}HuffmanTree,*pHuffmanTree;int iCount = 0;//叶子节点数
int iIndex = 1;//索引//-----------------------------------------void CreateBiTree(pBitree* pBitreeTemp);//创建二叉树
void CreatreArray(pHuffmanTree& pHuffmanTreeTemp,pBitree pBitreeTemp);//将二叉树每个节点的值作为权放进赫夫曼树中
pHuffmanTree InitHuffmanTree();//初始化赫夫曼树,
void CreateHuffmanTree(pHuffmanTree& pHuffmanTreeTemp);//创建赫夫曼树
int GetNode(pHuffmanTree& pHuffmanTreeTemp,int i);//获取赫夫曼树中位置0-i中值最小的节点的索引
void SelectNode(pHuffmanTree& pHuffmanTreeTemp,int i,int *m,int *n);//选择赫夫曼树数组中值最小的两个节点的索引(不包含已有父节点的节点)
void DestroyTree(pBitree* pBitreeTemp);
void DestroyHuffmanTree(pHuffmanTree& pHuffmanTreeTemp);
int main()
{int i;//创建二叉树pBitree pBitreeTemp;CreateBiTree(&pBitreeTemp);//初始化赫夫曼树pHuffmanTree pHuffmanTreeTemp = InitHuffmanTree();//初始化赫夫曼树的叶子节点的权CreatreArray(pHuffmanTreeTemp,pBitreeTemp);for(i = 1; i <= iCount ; i++){cout<<pHuffmanTreeTemp[i].weight<<" ";}cout<<endl;//创建赫夫曼树CreateHuffmanTree(pHuffmanTreeTemp);for(i = 1; i <= 2*iCount-1 ; i++){cout<<pHuffmanTreeTemp[i].weight<<" ";}cout<<endl;DestroyTree(&pBitreeTemp);DestroyHuffmanTree(pHuffmanTreeTemp);return 0;
}void CreateBiTree(pBitree* pBitreeTemp)
{int data;cin>>data;if(data == -1){return;}*pBitreeTemp = (pBitree)malloc(sizeof(Bitree));if(*pBitreeTemp == NULL){return;}(*pBitreeTemp)->data = data;(*pBitreeTemp)->lChild = NULL;(*pBitreeTemp)->rChild = NULL;CreateBiTree(&(*pBitreeTemp)->lChild);CreateBiTree(&(*pBitreeTemp)->rChild);iCount++;
}
pHuffmanTree InitHuffmanTree()
{int num = 2*iCount - 1;//赫夫曼树的节点总数为:叶子节点数*2-1pHuffmanTree pTemp = (pHuffmanTree)malloc(sizeof(HuffmanTree)*(num+1));//0位不存if(pTemp == NULL){return NULL;}for(int i = 0; i <= num; i++){pTemp[i].lChild = 0;pTemp[i].rChild = 0;pTemp[i].parent = 0;pTemp[i].weight = 0;}return pTemp;
}
void CreatreArray(pHuffmanTree& pHuffmanTreeTemp,pBitree pBitreeTemp)
{if(pBitreeTemp == NULL || pHuffmanTreeTemp == NULL){return;}pHuffmanTreeTemp[iIndex].weight = pBitreeTemp->data;iIndex++;CreatreArray(pHuffmanTreeTemp,pBitreeTemp->lChild);CreatreArray(pHuffmanTreeTemp,pBitreeTemp->rChild);
}
int GetNode(pHuffmanTree& pHuffmanTreeTemp,int i)
{int min = UINT_MAX;int flag;for(int j = 1; j <= i; j++){if(pHuffmanTreeTemp[j].weight < min && pHuffmanTreeTemp[j].parent == 0)//已有父节点的不算{min = pHuffmanTreeTemp[j].weight;flag = j;}}pHuffmanTreeTemp[flag].parent = 1;//防止两次调用获取的索引相同return flag;
}
void SelectNode(pHuffmanTree& pHuffmanTreeTemp,int i,int *m,int *n)//m为序号小的那个
{*m = GetNode(pHuffmanTreeTemp,i);*n = GetNode(pHuffmanTreeTemp,i);int t;if(*m > *n){t = *m;*m = *n;*n = t;}
}void CreateHuffmanTree(pHuffmanTree& pHuffmanTreeTemp)
{if(pHuffmanTreeTemp == NULL){return;}int m = 0,n = 0;for(int i = iCount+1;i <= 2*iCount-1; i++){SelectNode(pHuffmanTreeTemp,i-1,&m,&n);pHuffmanTreeTemp[m].parent = pHuffmanTreeTemp[n].parent = i;//构造两个最小权重的节点的父节点pHuffmanTreeTemp[i].lChild = m;pHuffmanTreeTemp[i].rChild = n;pHuffmanTreeTemp[i].weight = pHuffmanTreeTemp[m].weight+pHuffmanTreeTemp[n].weight;}}void DestroyTree(pBitree* pBitreeTemp)
{if(*pBitreeTemp == NULL){return;}if((*pBitreeTemp)->lChild){DestroyTree(&(*pBitreeTemp)->lChild);}if((*pBitreeTemp)->rChild){DestroyTree(&(*pBitreeTemp)->rChild);}free(*pBitreeTemp);*pBitreeTemp = NULL;
}void DestroyHuffmanTree(pHuffmanTree& pHuffmanTreeTemp)
{if(pHuffmanTreeTemp){free(pHuffmanTreeTemp);}pHuffmanTreeTemp = NULL;
}

测试:

图解构造过程:
1.首先将二叉树中的节点全部存到代表赫夫曼树的数组中,其余位置为0:
2.循环遍历该数组,每次找到最小权重的两个节点,之和作为其父节点的权重
3.循环一遍后,便得到赫夫曼树:

由二叉树构造赫夫曼树相关推荐

  1. php 二叉树 与赫夫曼树

    在学习图之前,中间休息了两天,感觉二叉树需要消化一下.所以中间去温习了下sql,推荐一本工具书<程序员的SQL金典>看名字不像一本好书,但是作为一个不错的SQL工具书还是可以小小备忘一下. ...

  2. 简述最优二叉树(赫夫曼树)

    什么是哈夫曼树: 给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权 ...

  3. 二叉树的应用——赫夫曼树

    1.赫夫曼树(最优二叉树)的基本概念 2.赫夫曼树的存储实现 根据二叉树性质: 非空二叉树,叶子节点数为n0,度为2的节点数为n2,则n0=n2+1. 可知n个叶子结点的赫夫曼树有2n-1个结点 3. ...

  4. 数据结构与算法之Huffman tree(赫夫曼树 / 霍夫曼树 / 哈夫曼树 / 最优二叉树)

    目录 赫夫曼树概述 定义 构造赫夫曼树步骤 代码实现 赫夫曼树概述 HuffmanTree因为翻译不同所以有其他的名字:赫夫曼树.霍夫曼树.哈夫曼树 赫夫曼树又称最优二叉树,是一种带权路径长度最短的二 ...

  5. 6.6.1最优二叉树(赫夫曼树)

    首先我们来看一个伪代码.这个是代表成绩的等级. 然后我们知道,每一次高考,学生的成绩分布应该接近某个比例,现在我们假如分别规律如下: 为此可以作出下面的这个树. 我们发现,概率分布主要是在70-79, ...

  6. 【赫夫曼树详解】赫夫曼树简介及java代码实现-数据结构07

    赫夫曼树(最优二叉树) 1. 简介 定义: 赫夫曼树是n个带权叶子结点构成的所有二叉树中,带权路径长度(WPL)最小的二叉树. 叶子结点的带权路径: 叶子结点权值*到根节点的路径长度(叶结点的层数) ...

  7. 赫夫曼树编码的算法及应用习题--数据结构

    赫夫曼树编码的算法及应用习题 1.构造赫夫曼树的方法 1.根据给定的n个权值{w1,w2,---wn},构成n棵二叉树的集合F={T1,T2...,Tn},其中每棵二叉树中只有一个带权为Wi的根结点, ...

  8. 赫夫曼树的定义及原理

    参考<大话数据结构>        以学生成绩为例进行分析,正常的学生成绩的分布范围如下: 下面的图是普通的学生成绩判断,粗略的看什么问题,可是通常都认为,一张好的考卷应该是让学生的成绩大 ...

  9. 赫夫曼树赫夫曼编码的创建

    目录 基础知识点 最优二叉树 如何构造赫夫曼树 赫夫曼编码 编码与压缩文件 代码 结构体设计 创建赫夫曼树 创建构建赫夫曼编码 基础知识点 赫夫曼树又称为最优树,是一种带权路径长短最短的树,有着广泛的 ...

最新文章

  1. CVPR2021 图像匹配挑战赛,双赛道冠亚军方案
  2. 特斯拉撤诉和解,小鹏汽车沉冤得雪:警惕自动驾驶领域的“美国陷阱”
  3. java int 127_Integer类型中奇怪的127和128
  4. 剑指offer(三):从尾到头打印链表
  5. opencv 学习笔记6:通道的拆分与合并
  6. android merge的作用,Android学习手记-merge
  7. 删除计算机文件的几种方法,电脑删除不了文件怎么办?教你几种好的处理方法,一学就会...
  8. 阿里云数据库产品专家胡航丽:数据库自动驾驶平台DAS重磅助力数据库领域智能未来...
  9. Linux Polkit 中的pkexec 组件存在的本地权限提升漏洞(CVE-2021-4034)修复方法及centos6和centos7的安装包
  10. CMake下载及安装
  11. js数组去重方法分析与总结
  12. java day60【 Spring 中的 JdbcTemplate[会用] 、Spring 中的事务控制 、Spring5 的新特性[了解] 】...
  13. DPDK收发包流程分析(一)
  14. phpstorm的安装和破解
  15. java mysql 公交车换乘查询算法_公交车路线查询系统后台数据库设计--换乘算法改进与优化...
  16. 【Unity入门计划】Unity2D动画(2)-脚本与混合树实现玩家角色动画过渡
  17. java vim编辑器的基本使用_vim编辑器之神的高效率使用
  18. 什么是双亲委派模型?双亲委派模型有何作用?
  19. sift特征检测与匹配
  20. 对抗海量表格数据,【华为2012实验室】没有选择复仇者联盟

热门文章

  1. 四种xml的解析方式
  2. 仿阿里云后台管理界面模板html源码——后台
  3. DebugView 简单使用
  4. 不要被新媒体营造的焦虑所绑架(咪蒙类账号的不道德)
  5. ZYNQ TTC使用方法
  6. vue-admin-实现登出功能
  7. 【Java】继承、多态、接口
  8. 小白学编程c语言,小白学编程,是先学C语言还是C++?
  9. Diabetes 糖尿病及其并发症.|2021/1/25(未完待续)
  10. checkbox 点击搜索失去焦点_jquery获取焦点和失去焦点事件代码