Cod sursa(job #2246713)

Utilizator paul_danutDandelion paul_danut Data 27 septembrie 2018 14:02:47
Problema Coduri Huffman Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#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;
}