#include <iostream>
#include <queue>
using namespace std;
// Вузол бінарного дерева для зберігання частот символів
struct TreeNode {
char ch;
int freq;
TreeNode* left;
TreeNode* right;
TreeNode(char c, int f) : ch(c), freq(f), left(nullptr), right(nullptr) {}
};
// Додає вузли в бінарне дерево пошуку
TreeNode* insert(TreeNode* root, char ch, int freq) {
if (!root) return new TreeNode(ch, freq);
if (ch < root->ch)
root->left = insert(root->left, ch, freq);
else if (ch > root->ch)
root->right = insert(root->right, ch, freq);
else
root->freq++; // Якщо символ вже є, збільшити його частоту
return root;
}
// Пошук символу в дереві
TreeNode* find(TreeNode* root, char ch) {
if (!root) return nullptr;
if (root->ch == ch) return root;
if (ch < root->ch)
return find(root->left, ch);
return find(root->right,ch);
}
// Побудова дерева Хаффмана
struct HuffmanNode {
char ch;
int freq;
HuffmanNode* left;
HuffmanNode* right;
HuffmanNode(char c, int f, HuffmanNode* l = nullptr, HuffmanNode* r = nullptr)
: ch(c), freq(f), left(l), right(r) {}
};
struct Compare {
bool operator()(HuffmanNode* a, HuffmanNode* b) {
return a->freq > b->freq;
}
};
// Функція обходу дерева частот та додавання вузлів у пріоритетну чергу
void traverse(TreeNode* node, priority_queue<HuffmanNode*, vector<HuffmanNode*>, Compare>& pq) {
if (!node) return;
pq.push(new HuffmanNode(node->ch, node->freq));
traverse(node->left, pq);
traverse(node->right, pq);
}
// Генерація кодів Хаффмана
void generateCodes(HuffmanNode* root, string code, vector<pair<char, string>>& codes) {
if (!root) return;
if (root->ch != '\0')
codes.emplace_back(root->ch, code);
generateCodes(root->left, code + "0", codes);
generateCodes(root->right, code + "1", codes);
}
int main() {
string text = "danylukoleksandra";
// Створення дерева частот символів
TreeNode* freqTree = nullptr;
for (char ch : text) {
TreeNode* node = find(freqTree, ch);
if (node)
node->freq++;
else
freqTree = insert(freqTree, ch, 1);
}
// Створення черги для побудови дерева Хаффмана
priority_queue<HuffmanNode*, vector<HuffmanNode*>, Compare> pq;
traverse(freqTree, pq);
while (pq.size() > 1) {
HuffmanNode* left = pq.top(); pq.pop();
HuffmanNode* right = pq.top(); pq.pop();
HuffmanNode* parent = new HuffmanNode('\0', left->freq + right->freq, left, right);
pq.push(parent);
}
HuffmanNode* root = pq.top();
vector<pair<char, string>> huffmanCodes;
generateCodes(root, "", huffmanCodes);
// Вивід кодів
cout << "Коди Хаффмана:\n";
for (const auto& pair : huffmanCodes)
cout << pair.first << ": " << pair.second << '\n';
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8cXVldWU+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKLy8g0JLRg9C30L7QuyDQsdGW0L3QsNGA0L3QvtCz0L4g0LTQtdGA0LXQstCwINC00LvRjyDQt9Cx0LXRgNGW0LPQsNC90L3RjyDRh9Cw0YHRgtC+0YIg0YHQuNC80LLQvtC70ZbQsgpzdHJ1Y3QgVHJlZU5vZGUgewogICAgY2hhciBjaDsKICAgIGludCBmcmVxOwogICAgVHJlZU5vZGUqIGxlZnQ7CiAgICBUcmVlTm9kZSogcmlnaHQ7CiAgICAKICAgIFRyZWVOb2RlKGNoYXIgYywgaW50IGYpIDogY2goYyksIGZyZXEoZiksIGxlZnQobnVsbHB0ciksIHJpZ2h0KG51bGxwdHIpIHt9Cn07CgovLyDQlNC+0LTQsNGUINCy0YPQt9C70Lgg0LIg0LHRltC90LDRgNC90LUg0LTQtdGA0LXQstC+INC/0L7RiNGD0LrRgwpUcmVlTm9kZSogaW5zZXJ0KFRyZWVOb2RlKiByb290LCBjaGFyIGNoLCBpbnQgZnJlcSkgewogICAgaWYgKCFyb290KSByZXR1cm4gbmV3IFRyZWVOb2RlKGNoLCBmcmVxKTsKICAgIAogICAgaWYgKGNoIDwgcm9vdC0+Y2gpCiAgICAgICAgcm9vdC0+bGVmdCA9IGluc2VydChyb290LT5sZWZ0LCBjaCwgZnJlcSk7CiAgICBlbHNlIGlmIChjaCA+IHJvb3QtPmNoKQogICAgICAgIHJvb3QtPnJpZ2h0ID0gaW5zZXJ0KHJvb3QtPnJpZ2h0LCBjaCwgZnJlcSk7CiAgICBlbHNlCiAgICAgICAgcm9vdC0+ZnJlcSsrOyAvLyDQr9C60YnQviDRgdC40LzQstC+0Lsg0LLQttC1INGULCDQt9Cx0ZbQu9GM0YjQuNGC0Lgg0LnQvtCz0L4g0YfQsNGB0YLQvtGC0YMKICAgIAogICAgcmV0dXJuIHJvb3Q7Cn0KCi8vINCf0L7RiNGD0Log0YHQuNC80LLQvtC70YMg0LIg0LTQtdGA0LXQstGWClRyZWVOb2RlKiBmaW5kKFRyZWVOb2RlKiByb290LCBjaGFyIGNoKSB7CiAgICBpZiAoIXJvb3QpIHJldHVybiBudWxscHRyOwogICAgaWYgKHJvb3QtPmNoID09IGNoKSByZXR1cm4gcm9vdDsKICAgIAogICAgaWYgKGNoIDwgcm9vdC0+Y2gpCiAgICAgICAgcmV0dXJuIGZpbmQocm9vdC0+bGVmdCwgY2gpOwogICAgcmV0dXJuIGZpbmQocm9vdC0+cmlnaHQsY2gpOwp9CgovLyDQn9C+0LHRg9C00L7QstCwINC00LXRgNC10LLQsCDQpdCw0YTRhNC80LDQvdCwCnN0cnVjdCBIdWZmbWFuTm9kZSB7CiAgICBjaGFyIGNoOwogICAgaW50IGZyZXE7CiAgICBIdWZmbWFuTm9kZSogbGVmdDsKICAgIEh1ZmZtYW5Ob2RlKiByaWdodDsKICAgIAogICAgSHVmZm1hbk5vZGUoY2hhciBjLCBpbnQgZiwgSHVmZm1hbk5vZGUqIGwgPSBudWxscHRyLCBIdWZmbWFuTm9kZSogciA9IG51bGxwdHIpCiAgICAgICAgOiBjaChjKSwgZnJlcShmKSwgbGVmdChsKSwgcmlnaHQocikge30KfTsKCnN0cnVjdCBDb21wYXJlIHsKICAgIGJvb2wgb3BlcmF0b3IoKShIdWZmbWFuTm9kZSogYSwgSHVmZm1hbk5vZGUqIGIpIHsKICAgICAgICByZXR1cm4gYS0+ZnJlcSA+IGItPmZyZXE7CiAgICB9Cn07CgovLyDQpNGD0L3QutGG0ZbRjyDQvtCx0YXQvtC00YMg0LTQtdGA0LXQstCwINGH0LDRgdGC0L7RgiDRgtCwINC00L7QtNCw0LLQsNC90L3RjyDQstGD0LfQu9GW0LIg0YMg0L/RgNGW0L7RgNC40YLQtdGC0L3RgyDRh9C10YDQs9GDCnZvaWQgdHJhdmVyc2UoVHJlZU5vZGUqIG5vZGUsIHByaW9yaXR5X3F1ZXVlPEh1ZmZtYW5Ob2RlKiwgdmVjdG9yPEh1ZmZtYW5Ob2RlKj4sIENvbXBhcmU+JiBwcSkgewogICAgaWYgKCFub2RlKSByZXR1cm47CgogICAgcHEucHVzaChuZXcgSHVmZm1hbk5vZGUobm9kZS0+Y2gsIG5vZGUtPmZyZXEpKTsKICAgIHRyYXZlcnNlKG5vZGUtPmxlZnQsIHBxKTsKICAgIHRyYXZlcnNlKG5vZGUtPnJpZ2h0LCBwcSk7Cn0KCi8vINCT0LXQvdC10YDQsNGG0ZbRjyDQutC+0LTRltCyINCl0LDRhNGE0LzQsNC90LAKdm9pZCBnZW5lcmF0ZUNvZGVzKEh1ZmZtYW5Ob2RlKiByb290LCBzdHJpbmcgY29kZSwgdmVjdG9yPHBhaXI8Y2hhciwgc3RyaW5nPj4mIGNvZGVzKSB7CiAgICBpZiAoIXJvb3QpIHJldHVybjsKICAgIGlmIChyb290LT5jaCAhPSAnXDAnKQogICAgICAgIGNvZGVzLmVtcGxhY2VfYmFjayhyb290LT5jaCwgY29kZSk7CiAgICAKICAgIGdlbmVyYXRlQ29kZXMocm9vdC0+bGVmdCwgY29kZSArICIwIiwgY29kZXMpOwogICAgZ2VuZXJhdGVDb2Rlcyhyb290LT5yaWdodCwgY29kZSArICIxIiwgY29kZXMpOwp9CgppbnQgbWFpbigpIHsKICAgIHN0cmluZyB0ZXh0ID0gImRhbnlsdWtvbGVrc2FuZHJhIjsKICAgIAogICAgLy8g0KHRgtCy0L7RgNC10L3QvdGPINC00LXRgNC10LLQsCDRh9Cw0YHRgtC+0YIg0YHQuNC80LLQvtC70ZbQsgogICAgVHJlZU5vZGUqIGZyZXFUcmVlID0gbnVsbHB0cjsKICAgIGZvciAoY2hhciBjaCA6IHRleHQpIHsKICAgICAgICBUcmVlTm9kZSogbm9kZSA9IGZpbmQoZnJlcVRyZWUsIGNoKTsKICAgICAgICBpZiAobm9kZSkKICAgICAgICAgICAgbm9kZS0+ZnJlcSsrOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnJlcVRyZWUgPSBpbnNlcnQoZnJlcVRyZWUsIGNoLCAxKTsKICAgIH0KCiAgICAvLyDQodGC0LLQvtGA0LXQvdC90Y8g0YfQtdGA0LPQuCDQtNC70Y8g0L/QvtCx0YPQtNC+0LLQuCDQtNC10YDQtdCy0LAg0KXQsNGE0YTQvNCw0L3QsAogICAgcHJpb3JpdHlfcXVldWU8SHVmZm1hbk5vZGUqLCB2ZWN0b3I8SHVmZm1hbk5vZGUqPiwgQ29tcGFyZT4gcHE7CiAgICB0cmF2ZXJzZShmcmVxVHJlZSwgcHEpOwoKICAgIHdoaWxlIChwcS5zaXplKCkgPiAxKSB7CiAgICAgICAgSHVmZm1hbk5vZGUqIGxlZnQgPSBwcS50b3AoKTsgcHEucG9wKCk7CiAgICAgICAgSHVmZm1hbk5vZGUqIHJpZ2h0ID0gcHEudG9wKCk7IHBxLnBvcCgpOwogICAgICAgIEh1ZmZtYW5Ob2RlKiBwYXJlbnQgPSBuZXcgSHVmZm1hbk5vZGUoJ1wwJywgbGVmdC0+ZnJlcSArIHJpZ2h0LT5mcmVxLCBsZWZ0LCByaWdodCk7CiAgICAgICAgcHEucHVzaChwYXJlbnQpOwogICAgfQoKICAgIEh1ZmZtYW5Ob2RlKiByb290ID0gcHEudG9wKCk7CiAgICB2ZWN0b3I8cGFpcjxjaGFyLCBzdHJpbmc+PiBodWZmbWFuQ29kZXM7CiAgICBnZW5lcmF0ZUNvZGVzKHJvb3QsICIiLCBodWZmbWFuQ29kZXMpOwoKICAgIC8vINCS0LjQstGW0LQg0LrQvtC00ZbQsgogICAgY291dCA8PCAi0JrQvtC00Lgg0KXQsNGE0YTQvNCw0L3QsDpcbiI7CiAgICBmb3IgKGNvbnN0IGF1dG8mIHBhaXIgOiBodWZmbWFuQ29kZXMpCiAgICAgICAgY291dCA8PCBwYWlyLmZpcnN0IDw8ICI6ICIgPDwgcGFpci5zZWNvbmQgPDwgJ1xuJzsKCiAgICByZXR1cm4gMDsKfQo=