Pagini recente » Cod sursa (job #2296029) | Cod sursa (job #2246713)
#include <fstream>
#include <queue>
#include <vector>
#include <list>
#include <algorithm>
#include <iostream>
struct Nod { int val; Nod *left, *right;};
struct cmp {
bool operator()(Nod* x, Nod* y) const
{
return x->val > y->val;
}
};
std::priority_queue<Nod*, std::vector<Nod*>, cmp> heap;
Nod* Huffman(std::priority_queue<Nod*, std::vector<Nod*>, cmp>& heap, unsigned long long int& lg)
{
lg = 0;
while (heap.size()>1)
{
Nod *c1 = heap.top(); heap.pop();
Nod *c2 = heap.top(); heap.pop();
// std::cout<< "left:" << c1->val << ' ' << "right:" << c2->val << "sum: " << c1->val + c2->val <<'\n';
Nod* p = new Nod;
p->val = c1->val + c2->val;
lg += p->val;
p->left = c1;
p->right = c2;
heap.push(p);
}
return heap.top();
}
void PostOrderTraversal(Nod* nod, std::list<std::pair<size_t, size_t>>& result, unsigned long long int val = 0, size_t length = 0U)
{
if( nullptr == nod->left && nullptr == nod->right )
{
//std::cout << nod->val << "\n";
result.push_back(std::make_pair(length, val));
}
else
{
if( nullptr != nod->left )
{
// std::cout << nod->val << "->" << "l \n";
PostOrderTraversal(nod->left, result, val << 1, length + 1);
// std::cout << nod->val << "<-" << "l \n";
}
if( nullptr != nod->right )
{
// std::cout << nod->val << "->" << "r \n";
PostOrderTraversal(nod->right, result, (val << 1) + 1, length + 1);
//std::cout << nod->val << "<-" << "r \n";
}
}
}
int main()
{
std::ifstream fin("huffman.in");
std::ofstream fout("huffman.out");
auto n = 0U;
auto x = 0ULL;
fin >> n;
for (auto i = 0U; i < n; ++i)
{
fin >> x;
Nod *nod = new Nod;
nod->val = x;
nod->left = nullptr;
nod->right = nullptr;
heap.push(nod);
}
std::list<std::pair<size_t, size_t>> result;
auto lg = 0ULL;
auto root = Huffman(heap, lg);
PostOrderTraversal(root, result);
fout << lg << '\n';
std::for_each (result.cbegin(), result.cend(), [&fout](auto p){
fout << p.first << ' ' << p.second << '\n';
});
return 0;
}