赞
踩
在一棵树中,从一个结点到另外一个结点所经过得所有的结点,我们成为两个结点之间得路径。
从A到叶子结点E的路径就是:A->B->D->E;
在一棵树中,从一个几点到另外一个结点所经过的边的数量,就是路径长度。
从根结点A到叶子结点E,共经过了3条边,因此路径长度是3。
树的每一个结点,都可以拥有自己的“权重”(weight),权重在不同的算法中起到不同的作用。
结点的带权路径长度 = 树的根节点到该结点的路径长度 * 该结点权重。
假设结点E的权重是2,从根结点到结点E的路径长度是3,因此E结点的带权路径长度为:2*3 = 6
在一棵树中,所有的叶子结点的带权路径长度之和,被称为树的带权路径长度,简称WPL
我们知道了树的带权路径的计算方式,哈夫曼就是在树的叶子结点和权重确定的情况下,带权路径最小的二叉树即为 最优二叉树(也就是哈夫曼树)
给定权重 1 ,2 ,3 ,4
明显右边小于左边。 因此右边就是哈夫曼树。
但是哈夫曼树不止一种。
如下:
共有6个叶子结点,权重分别是:1,4,7,11,22,32
把每一个结点都当做一棵独立的树。因此便形成一片森林
当队列中仅有一个结点,说明整个森林已经合并成一棵树,这棵树就是哈夫曼树。
如果出现相加和与待选择权重队列中的重复,则可以选择新加入的或者原队列中的均可。
最终:
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; const int n = 8;//leaf const int m = n * 2;//node typedef unsigned int WeightType; typedef unsigned int NodeType; typedef struct { WeightType weight; NodeType parent, leftchild, rightchild; }HTNode; typedef HTNode HuffManTree[m];//静态存储 数组类型
基本概念: 不满足先进先出的条件,更像是数据类型中的堆,优先级队列每次出队的元素不是队首元素,而是优先级最高的元素,这个优先级可以通过元素的大小进行定义。
比如定义元素越大优先级越高,那么每次出队,都是将当前队列中最大的那个元素出队。
现在看优先级队列是不是就是“堆”了,如果最大的元素优先级最高,那么每次出队的就是当前队列中最大的元素,那么队列实际就相当于一个大顶堆,每次将堆根节点元素弹出,重新维护大顶堆,就可以实现一个优先级队列。
priority_queue<typename, container, functional>
typename
是数据的类型;
container
是容器类型,可以是vector,queue等用数组实现的容器,不能是list,默认可以用vector;
functional
是比较的方式,默认是大顶堆(就是元素值越大,优先级越高);
priority_queue<int, vector<int>, less<int>> p;
构造一个小顶堆,堆中大于当前节点的元素需要下沉,因此使用greater
priority_queue<string, vector<string>, greater<string>> p;
void Print_HuffManTree(HuffManTree hft)
{
for (int i = 1; i < m; ++i)
{
printf("index :%3d weight: %3d parent :%3d left:%3d right: %3d\n",
i, hft[i].weight,hft[i].parent,hft[i].leftchild,hft[i].rightchild);
}
}
void Init_HuffManTree(HuffManTree hft, WeightType weight[])
{
memset(hft, 0, sizeof(HuffManTree));
for (int i = 0; i < n; ++i)
{
hft[i+1].weight = weight[i]; //初始化权重
}
//printf("HuffmanTree = %d\n", sizeof(HuffmanTree));
//printf("hft: size %d\n", sizeof(hft));
//printf("w: size%d \n", sizeof(weight));
}
struct IndexWeight { int index; //下标 WeightType weight;//权值参与比较 operator WeightType() const { return weight; } //把weight强转为WeightType类型 }; void CreateHuffManTree(HuffManTree hft) { priority_queue<IndexWeight, vector<IndexWeight>, std::greater<IndexWeight>> qu; for (int i = 1; i <= n; ++i) { qu.push(IndexWeight{ i,hft[i].weight }); } int k = n + 1; while (!qu.empty()) { if (qu.empty()) break; //将最小的两个值出队列 IndexWeight left = qu.top(); qu.pop(); if (qu.empty()) break; IndexWeight right = qu.top(); qu.pop(); hft[k].weight = left.weight + right.weight; hft[k].leftchild = left.index; hft[k].rightchild = right.index; hft[left.index].parent = k; hft[right.index].parent = k; qu.push(IndexWeight{ k,hft[k].weight }); k++; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。