任务描述
本关任务:编程实现哈夫曼树的的构建,并求其带权路径长度
相关知识
完成本关你需要了解一下内容: 1、哈夫曼树的定义; 2、哈夫曼树的存储结构; 3、哈夫曼树的构造算法; 4、哈夫曼树带权路径长度计算方法
1、哈夫曼树的定义 给定一组具有确定权值的叶子结点,构造出带权路径长度最小的二叉树即为该组叶子结点所构成的哈夫曼树。 2、哈夫曼树的存储结构 哈夫曼树可以采用双亲孩子仿真指针存储结构进行存储,其定义如下:
typedef struct //定义双亲孩子仿真指针结构体
{
datatype data; // 本关所求解问题与结点的值无关,这个数据项可忽略
int weight ;
/* 用来存放各个结点的权值*/
int parent, lchild,rchild ; /* 双亲孩子仿真指针*/
}HTNode, * HuffmanTree; //n个叶子结点的哈夫曼树共有2*n-1个结点
HuffmanTree=(HTNode *) malloc(sizeof(HTNode)*2*n-1);
3、哈夫曼树构造的算法 初始化长度为2n-1的仿真指针中各叶子结点的初始值(包括parent、lchild、rchild)。 for(i=n;i<2n-1;i++)//合并树 { 在parent值为-1的结点中找出weight值最小的两个结点node1和node2 用数组的第i个结点作为根结点来合并node1和node2。(即修改node1和node2的parrent值,修改第i个结点的weight、lchild、rchild值) } 例如:5个结点权值分别为3,4,5,6,12的结点,初始化9个结点的哈夫曼数组如下图1所示,构建完成的哈夫曼树如下图2所示,其图示表示入下图3所示。 图1初始状态
图2终止状态
图3哈夫曼树的图示表示
4、哈夫曼树带权路径长度计算方法
带权路径长度:从二叉树的根结点到二叉树中所有叶结点的路径长度与相应叶结点权值的乘积之和称作该二叉树的(WPL),即:
同时, WPL=所有非叶子结点的权值之和。
图3所表示的哈夫曼树的带权路径权值
WPL=12+(4+3+5+6)*3=66 (根据叶子结点的带权路径权值计算) =20+18+7+11=66 (根据非叶子结点的权值计算)
编程要求
根据提示,在右侧代码编辑器中,补充完整initHaffTree
、creatHaffTree
、WPL
等函数,完成根据输入的叶子结点权值,构造相应的哈夫曼树,求其带权路径长度,并输出。
输入输出说明
输入为一组测试用例占一行,先输入叶子结点个数n(1<=n<=100),然后输入n个叶子叶子结点的int型的权值,输出由这n个叶子结点构成的哈夫曼树的带权路径权值 例: 输入 5 3 4 5 6 12 66
不用建树
#include<iostream> #include<stdio.h> #include<queue> using namespace std; priority_queue<int,vector<int>,greater<int> > Q; int main(){ int N; scanf("%d",&N); while(!Q.empty()) Q.pop(); for(int i = 0; i < N; i++){ int x; scanf("%d",&x); Q.push(x); } int ans = 0; while(!Q.empty()&&Q.size()>1){ int a = Q.top(); Q.pop(); int b = Q.top(); Q.pop(); ans += a + b; Q.push(a+b); } printf("%d ",ans); }
建树的以后再补。。