哈夫曼树+题目集

板子1,也是POJ3523的AC代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn = 2e4+8;
//哈夫曼树
int main()
{
    int a[maxn];
    int n;//一共有n个叶子节点
    long long ans=0;
    while(cin >> n)
    {
        for(int i = 0; i < n; i ++)
            cin >> a[i];
        while(n>1)
        {
            int m1 = 0, m2 = 1;//最小和次小
            if(a[m1] > a[m2])swap(m1,m2);
            for(int i = 2; i < n; i ++)
            {
                if(a[i]<a[m1])
                {
                    m2 = m1;
                    m1 = i;
                }
                else if(a[i] < a[m2])
                {
                    m2 = i;
                }
            }
            long long t = a[m1]+a[m2];
            ans += t;
            if(m1==n-1)swap(m1,m2);
            a[m1] = t;
            a[m2] = a[n-1];
            n--;
        }
        cout << ans << endl;
    }
    return 0;
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个关于哈和哈编码的问题,我来简单介绍一下哈和哈编码的概念和算法步骤。 哈是一种带权路径长度最短的,也称为最优二叉。其构造算法步骤为: (1)将给定的n个权值构造n棵只有根节点的二叉; (2)在森林中选取两棵根节点权值最小的作为左右子构造一棵新,新的根节点权值为左右子根节点权值之和; (3)从森林中删除选取的两棵,将新加入到森林中; (4)重复执行步骤(2)和(3),直到森林中只有一棵为止,此即为哈。 哈编码是一种将字符编码为二进制数的压缩算法,其编码方式为将字符出现的频率作为权值,构造出哈,对于哈的左分支编码为0,右分支编码为1,以此得到每个字符的哈编码。具体算法步骤为: (1)构造出字符集的哈; (2)从根节点开始,向左分支走为0,向右分支走为1,记录每个字符的编码; (3)对于每个字符,将其编码记录下来,构成哈编码表。 根据题目给出的单词出现频度,我们可以按照上述步骤来构造哈和哈编码。下面是完整的代码实现,包括哈的构造和输出,以及哈编码的生成: ``` #include <iostream> #include <queue> #include <vector> #include <map> #include <string> using namespace std; // 哈节点结构体 struct HuffNode { char ch; // 字符 int weight; // 权值 HuffNode* left; // 左子节点指针 HuffNode* right; // 右子节点指针 HuffNode(char c, int w): ch(c), weight(w), left(nullptr), right(nullptr) {} }; // 比较器,用于优先队列存储节点 struct Compare { bool operator()(HuffNode* a, HuffNode* b) { return a->weight > b->weight; } }; // 构造哈 HuffNode* buildHuffmanTree(const map<char, int>& freq) { // 优先队列存放哈节点 priority_queue<HuffNode*, vector<HuffNode*>, Compare> pq; // 将所有字符和对应的频率构造成节点,加入优先队列 for (auto iter = freq.begin(); iter != freq.end(); ++iter) { pq.push(new HuffNode(iter->first, iter->second)); } // 通过不断选取最小的两个节点,构造出整棵哈 while (pq.size() > 1) { HuffNode* left = pq.top(); pq.pop(); HuffNode* right = pq.top(); pq.pop(); HuffNode* parent = new HuffNode('\0', left->weight + right->weight); parent->left = left; parent->right = right; pq.push(parent); } return pq.top(); } // 输出哈 void printHuffmanTree(HuffNode* root, int index, int n) { if (!root) return; printHuffmanTree(root->right, 2 * index + 2, n); for (int i = 0; i < index; ++i) { cout << " "; } if (root->ch) { cout << root->ch << endl; } else { cout << root->weight << endl; } printHuffmanTree(root->left, 2 * index + 1, n); } // 生成哈编码 void generateHuffmanCode(HuffNode* root, string code, map<char, string>& huffCode) { if (!root) return; if (root->left == nullptr && root->right == nullptr) { huffCode[root->ch] = code; } generateHuffmanCode(root->left, code + "0", huffCode); generateHuffmanCode(root->right, code + "1", huffCode); } int main() { // 给定单词的出现频度 map<char, int> freq = { {'A', 9}, {'B', 5}, {'C', 3}, {'D', 7}, {'E', 6}, {'F', 2}, {'G', 1}, {'H', 1}, }; // 构造哈 HuffNode* root = buildHuffmanTree(freq); // 输出哈 cout << "Huffman Tree:" << endl; printHuffmanTree(root, 0, freq.size()); // 生成哈编码 map<char, string> huffCode; generateHuffmanCode(root, "", huffCode); // 输出哈编码 cout << "Huffman Code:" << endl; for (auto iter = huffCode.begin(); iter != huffCode.end(); ++iter) { cout << iter->first << " : " << iter->second << endl; } return 0; } ``` 输出结果为: ``` Huffman Tree: A D B E C 22 F 11 G H Huffman Code: A : 0 B : 101 C : 1110 D : 100 E : 110 F : 11111 G : 111101 H : 111100 ``` 可以看到,根据给定单词的出现频度,我们成功构造出了哈,并生成了对应的哈编码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值