#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* i = nullptr, HuffmanNode* r = nullptr): ch(c), freq(f), 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);
}
string decode(string encoded, HuffmanNode* root) {
string decoded="";
HuffmanNode* current=root;
for (char c : encoded) {
if (c=='0') {
current=current->left;
}
else {
current=current->right;
}
if (current->ch!='\0') {
decoded+=current->ch;
current=root;
}
}
return decoded;
}
void in_order(HuffmanNode* node) {
if (node==nullptr) return;
if (node->left!=nullptr) {
cout<<node->ch<<"_"<<node->freq<<"--"<<node->left->ch<<"_"<<node->left->freq<<endl;
in_order(node->left);
}
if (node->right!=nullptr) {
cout<<node->ch<<"_"<<node->freq<<"--"<<node->right->ch<<"_"<<node->right->freq<<endl;
in_order(node->right);
}
}
// TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
int main() {
string text="TsybaniakVlada";
//Створення дерева частот символів
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';
cout<<endl;
string encoded="";
for (char c:text) {
for (const auto&code:huffmanCodes) {
if (code.first==c) {
encoded+=code.second;
break;
}
}
}
cout<<"Encoded Text: "<<encoded<<endl;
string decoded=decode(encoded, root);
cout<<"Decoded Text: "<< decoded<<endl;
in_order(root);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8cXVldWU+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Ci8v0JLRg9C30L7QuyDQsdGW0L3QsNGA0L3QvtCz0L4g0LTQtdGA0LXQstCwINC00LvRjyDQt9Cx0LXRgNGW0LPQsNC90L3RjyDRh9Cw0YHRgtC+0YIg0YHQuNC80LLQvtC70ZbQsgpzdHJ1Y3QgVHJlZU5vZGUgewogICAgY2hhciBjaDsKICAgIGludCBmcmVxOwogICAgVHJlZU5vZGUqIGxlZnQ7CiAgICBUcmVlTm9kZSogcmlnaHQ7CiAgICBUcmVlTm9kZShjaGFyIGMsIGludCBmKTogY2goYyksIGZyZXEoZiksIGxlZnQobnVsbHB0ciksIHJpZ2h0KG51bGxwdHIpe30KfTsKCi8v0JTQvtC00LDRlCDQstGD0LfQu9C4INCyINCx0ZbQvdCw0YDQvdC1INC00LXRgNC10LLQviDQv9GD0YjRg9C60YMKVHJlZU5vZGUqIGluc2VydChUcmVlTm9kZSogcm9vdCwgY2hhciBjaCwgaW50IGZyZXEpIHsKICAgIGlmICghcm9vdCkgcmV0dXJuIG5ldyBUcmVlTm9kZShjaCwgZnJlcSk7CgogICAgaWYgKGNoPHJvb3QtPmNoKQogICAgICAgIHJvb3QtPmxlZnQ9aW5zZXJ0KHJvb3QtPmxlZnQsIGNoLCBmcmVxKTsKICAgIGVsc2UgaWYgKGNoPnJvb3QtPmNoKQogICAgICAgIHJvb3QtPnJpZ2h0PWluc2VydChyb290LT5yaWdodCwgY2gsIGZyZXEpOwogICAgZWxzZQogICAgICAgIHJvb3QtPmZyZXErKzsgLy/Qr9C60YnQviDRgdC40LzQstC+0Lsg0LLQttC1INGULCDQt9Cx0ZbQu9GM0YjQuNGC0Lgg0LnQvtCz0L4g0YfQsNGB0YLQvtGC0YMKCiAgICByZXR1cm4gcm9vdDsKfQovL9Cf0L7RiNGD0Log0YHQuNC80LLQvtC70YMg0YMg0LTQtdGA0LXQstGWClRyZWVOb2RlKmZpbmQoVHJlZU5vZGUqIHJvb3QsIGNoYXIgY2gpIHsKICAgIGlmICghcm9vdCkgcmV0dXJuIG51bGxwdHI7CiAgICBpZiAocm9vdC0+Y2g9PWNoKSByZXR1cm4gcm9vdDsKCiAgICBpZiAoY2g8cm9vdC0+Y2gpCiAgICAgICAgcmV0dXJuIGZpbmQocm9vdC0+bGVmdCwgY2gpOwogICAgcmV0dXJuIGZpbmQocm9vdC0+cmlnaHQsIGNoKTsKfQovL9Cf0L7QsdGD0LTQvtCy0LAg0LTQtdGA0LXQstCwINCl0LDRhNGE0LzQsNC90LAKc3RydWN0IEh1ZmZtYW5Ob2RlIHsKICAgIGNoYXIgY2g7CiAgICBpbnQgZnJlcTsKICAgIEh1ZmZtYW5Ob2RlKiBsZWZ0OwogICAgSHVmZm1hbk5vZGUqIHJpZ2h0OwoKICAgIEh1ZmZtYW5Ob2RlKGNoYXIgYywgaW50IGYsIEh1ZmZtYW5Ob2RlKiBpID0gbnVsbHB0ciwgSHVmZm1hbk5vZGUqIHIgPSBudWxscHRyKTogY2goYyksIGZyZXEoZiksIHJpZ2h0KHIpe30KfTsKCnN0cnVjdCBDb21wYXJlIHsKICAgIGJvb2wgb3BlcmF0b3IoKShIdWZmbWFuTm9kZSogYSwgSHVmZm1hbk5vZGUqIGIpIHsKICAgICAgICByZXR1cm4gYS0+ZnJlcT5iLT5mcmVxOwogICAgfQp9OwoKLy/QpNGD0L3QutGG0ZbRjyDQvtCx0YXQvtC00YMg0LTQtdGA0LXQstCwINGH0LDRgdGC0L7RgiDRgtCwINC00L7QtNCw0LLQsNC90L3RjyDQstGD0LfQu9GW0LIg0YMg0L/RgNC40L7RgNGW0YLQtdGC0L3RgyDRh9C10YDQs9GDCnZvaWQgdHJhdmVyc2UoVHJlZU5vZGUqIG5vZGUsIHByaW9yaXR5X3F1ZXVlPEh1ZmZtYW5Ob2RlKiwgdmVjdG9yPEh1ZmZtYW5Ob2RlKj4sIENvbXBhcmU+JnBxKSB7CiAgICBpZiAoIW5vZGUpIHJldHVybjsKCiAgICBwcS5wdXNoKG5ldyBIdWZmbWFuTm9kZShub2RlLT5jaCwgbm9kZS0+ZnJlcSkpOwogICAgdHJhdmVyc2Uobm9kZS0+bGVmdCwgcHEpOwogICAgdHJhdmVyc2Uobm9kZS0+cmlnaHQsIHBxKTsKfQoKLy/Qk9C10L3QtdGA0LDRhtGW0Y8g0LrQvtC00ZbQsiDQpdCw0YTRhNC80LDQvdCwCnZvaWQgZ2VuZXJhdGVDb2RlcyhIdWZmbWFuTm9kZSogcm9vdCwgc3RyaW5nIGNvZGUsIHZlY3RvcjxwYWlyPGNoYXIsIHN0cmluZz4+JmNvZGVzKSB7CiAgICBpZiAoIXJvb3QpIHJldHVybjsKICAgIGlmIChyb290LT5jaCAhPSdcMCcpCiAgICAgICAgY29kZXMuZW1wbGFjZV9iYWNrKHJvb3QtPmNoLCBjb2RlKTsKCiAgICBnZW5lcmF0ZUNvZGVzKHJvb3QtPmxlZnQsIGNvZGUgKyAiMCIsIGNvZGVzKTsKICAgIGdlbmVyYXRlQ29kZXMocm9vdC0+cmlnaHQsIGNvZGUgKyAiMSIsIGNvZGVzKTsKfQpzdHJpbmcgZGVjb2RlKHN0cmluZyBlbmNvZGVkLCBIdWZmbWFuTm9kZSogcm9vdCkgewogICAgc3RyaW5nIGRlY29kZWQ9IiI7CiAgICBIdWZmbWFuTm9kZSogY3VycmVudD1yb290OwogICAgZm9yIChjaGFyIGMgOiBlbmNvZGVkKSB7CiAgICAgICAgaWYgKGM9PScwJykgewogICAgICAgICAgICBjdXJyZW50PWN1cnJlbnQtPmxlZnQ7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBjdXJyZW50PWN1cnJlbnQtPnJpZ2h0OwogICAgICAgIH0KCiAgICAgICAgaWYgKGN1cnJlbnQtPmNoIT0nXDAnKSB7CiAgICAgICAgICAgIGRlY29kZWQrPWN1cnJlbnQtPmNoOwogICAgICAgICAgICBjdXJyZW50PXJvb3Q7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGRlY29kZWQ7Cn0KCnZvaWQgaW5fb3JkZXIoSHVmZm1hbk5vZGUqIG5vZGUpIHsKICAgIGlmIChub2RlPT1udWxscHRyKSByZXR1cm47CiAgICBpZiAobm9kZS0+bGVmdCE9bnVsbHB0cikgewogICAgICAgIGNvdXQ8PG5vZGUtPmNoPDwiXyI8PG5vZGUtPmZyZXE8PCItLSI8PG5vZGUtPmxlZnQtPmNoPDwiXyI8PG5vZGUtPmxlZnQtPmZyZXE8PGVuZGw7CiAgICAgICAgaW5fb3JkZXIobm9kZS0+bGVmdCk7CiAgICB9CiAgICBpZiAobm9kZS0+cmlnaHQhPW51bGxwdHIpIHsKICAgICAgICBjb3V0PDxub2RlLT5jaDw8Il8iPDxub2RlLT5mcmVxPDwiLS0iPDxub2RlLT5yaWdodC0+Y2g8PCJfIjw8bm9kZS0+cmlnaHQtPmZyZXE8PGVuZGw7CiAgICAgICAgaW5fb3JkZXIobm9kZS0+cmlnaHQpOwogICAgfQp9Ci8vIFRJUCBUbyA8Yj5SdW48L2I+IGNvZGUsIHByZXNzIDxzaG9ydGN1dCBhY3Rpb25JZD0iUnVuIi8+IG9yIGNsaWNrIHRoZSA8aWNvbiBzcmM9IkFsbEljb25zLkFjdGlvbnMuRXhlY3V0ZSIvPiBpY29uIGluIHRoZSBndXR0ZXIuCmludCBtYWluKCkgewogICAgc3RyaW5nIHRleHQ9IlRzeWJhbmlha1ZsYWRhIjsKCiAgICAvL9Ch0YLQstC+0YDQtdC90L3RjyDQtNC10YDQtdCy0LAg0YfQsNGB0YLQvtGCINGB0LjQvNCy0L7Qu9GW0LIKICAgIFRyZWVOb2RlKiBmcmVxVHJlZSA9IG51bGxwdHI7CiAgICBmb3IgKGNoYXIgY2ggOiB0ZXh0KSB7CiAgICAgICAgVHJlZU5vZGUqIG5vZGUgPSBmaW5kKGZyZXFUcmVlLCBjaCk7CiAgICAgICAgaWYgKG5vZGUpCiAgICAgICAgICAgIG5vZGUtPmZyZXErKzsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZyZXFUcmVlID0gaW5zZXJ0KGZyZXFUcmVlLCBjaCwgMSk7CiAgICB9CgogICAgLy/QodGC0LLQvtGA0LXQvdC90Y8g0YfQtdGA0LPQuCDQtNC70Y8g0L/QvtCx0YPQtNC+0LLQuCDQtNC10YDQtdCy0LAg0KXQsNGE0YTQvNCw0L3QsAogICAgcHJpb3JpdHlfcXVldWU8SHVmZm1hbk5vZGUqICwgdmVjdG9yPEh1ZmZtYW5Ob2RlKj4sIENvbXBhcmU+IHBxOwogICAgdHJhdmVyc2UoZnJlcVRyZWUsIHBxKTsKCiAgICB3aGlsZSAocHEuc2l6ZSgpID4gMSkgewogICAgICAgIEh1ZmZtYW5Ob2RlKiBsZWZ0PXBxLnRvcCgpOyBwcS5wb3AoKTsKICAgICAgICBIdWZmbWFuTm9kZSogcmlnaHQgPSBwcS50b3AoKTsgcHEucG9wKCk7CiAgICAgICAgSHVmZm1hbk5vZGUqIHBhcmVudCA9IG5ldyBIdWZmbWFuTm9kZSgnXDAnLCBsZWZ0LT5mcmVxICsgcmlnaHQtPmZyZXEsIGxlZnQsIHJpZ2h0KTsKICAgICAgICBwcS5wdXNoKHBhcmVudCk7CiAgICB9CgogICAgSHVmZm1hbk5vZGUqIHJvb3QgPSBwcS50b3AoKTsKICAgIHZlY3RvciA8cGFpcjxjaGFyLCBzdHJpbmc+PiBodWZmbWFuQ29kZXM7CiAgICBnZW5lcmF0ZUNvZGVzKHJvb3QsICIiLCBodWZmbWFuQ29kZXMpOwoKICAgIC8v0JLQuNCy0ZbQtCDQutC+0LTRltCyCiAgICBjb3V0PDwi0JrQvtC00Lgg0KXQsNGE0YTQvNCw0L3QsDpcbiI7CiAgICBmb3IgKGNvbnN0IGF1dG8mIHBhaXIgOiBodWZmbWFuQ29kZXMpCiAgICAgICAgY291dDw8IHBhaXIuZmlyc3QgPDwgIjogIjw8cGFpci5zZWNvbmQ8PCdcbic7CgogICAgY291dDw8ZW5kbDsKCiAgICBzdHJpbmcgZW5jb2RlZD0iIjsKICAgIGZvciAoY2hhciBjOnRleHQpIHsKICAgICAgICBmb3IgKGNvbnN0IGF1dG8mY29kZTpodWZmbWFuQ29kZXMpIHsKICAgICAgICAgICAgaWYgKGNvZGUuZmlyc3Q9PWMpIHsKICAgICAgICAgICAgICAgIGVuY29kZWQrPWNvZGUuc2Vjb25kOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBjb3V0PDwiRW5jb2RlZCBUZXh0OiAiPDxlbmNvZGVkPDxlbmRsOwogICAgc3RyaW5nIGRlY29kZWQ9ZGVjb2RlKGVuY29kZWQsIHJvb3QpOwogICAgY291dDw8IkRlY29kZWQgVGV4dDogIjw8IGRlY29kZWQ8PGVuZGw7CgogICAgaW5fb3JkZXIocm9vdCk7CiAgICByZXR1cm4gMDsKCn0=