zoukankan      html  css  js  c++  java
  • 算法笔记--数据结构--哈夫曼树

    哈夫曼树(最优二叉树)

    定义:已知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

  • 相关阅读:
    7.15--7.19学习小结
    关于CStdioFile的使用问题
    【EOJ Monthly 2018.7】【D数蝌蚪】
    【HDOJ1051】【排序+LIS】【贪心】
    【HDOJ1045】【DFS】
    【递推】【HDOJ】
    【带权并查集】【HDOJ】
    【次小生成树】【Kruskal】【prim】【转】
    【HDOJ4857】【反向拓扑排序】
    【HDOJ1069】【动态规划】
  • 原文地址:https://www.cnblogs.com/zgqcn/p/12709734.html
Copyright © 2011-2022 走看看