Loading

算法笔记--数据结构--哈夫曼树

哈夫曼树(最优二叉树)

定义:已知n个数,寻找一棵树,使得树的所有叶子节点的权值恰好为这n个数,并且使得这棵树的带权路径长度最小

  • 带权路径长度:根结点到叶结点经过的边数 * 结点权重
  • 树的带权路径长度:所有叶子结点的带权路径长度之和

如,对于1、2、2、3、6这几个值来构建哈夫曼树:

Snipaste_2020-04-15_23-54-09

Snipaste_2020-04-15_23-54-26

Snipaste_2020-04-15_23-54-44

Snipaste_2020-04-15_23-55-03

Snipaste_2020-04-15_23-55-24

哈夫曼树的构建思想:反复选择最小的元素,合并,直到只剩下一个元素。

所以, 可以利用小堆来实现(优先队列)

#include<cstdio>
#include<queue>
using namespace std;
// 小顶堆的优先队列
priority_queue<long long, vector<long long>, greater<long long>> q;

int main(){
    int n;
    long long temp, x, y, ans = 0;
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        scanf("%lld", &temp);
        q.push(temp);		// 将初始重量压入优先队列
    }
    while(q.size() > 1){	// 只有优先队列中至少有两个元素
        x = q.top();
        q.pop();
        y = q.top();
        q.pop();
        q.push(x, y);		'// 取出堆顶两个元素,求和后压入优先队列
        ans += x + y; 		// 累加求和
    }
    printf("%lld", ans);
    return 0;
}

哈夫曼编码

哈夫曼编码是针对字符串来讲的,只有对确定的字符串,才能根据其中各个字符出现的次数建立哈弗曼树,于是才有哈弗曼编码。字符出现的次数为树的叶子结点。

Snipaste_2020-04-16_00-06-59

Write by Gqq

posted @ 2020-04-16 00:08  ZHGQCN  阅读(238)  评论(0编辑  收藏  举报