Pagini recente » Cod sursa (job #2940714) | Cod sursa (job #12872) | Cod sursa (job #2068440) | Cod sursa (job #26979) | Cod sursa (job #2077476)
#include <iostream>
#include <fstream>
using namespace std;
struct Nod
{
int numarAparitii;
int indice;
Nod *stanga;
Nod *dreapta;
};
const int numarMaximNoduri = 2000000;
struct Coada
{
Nod *nod[numarMaximNoduri];
int inceput;
int sfarsit;
void initializeaza()
{
inceput = 0;
sfarsit = -1;
}
void adauga(Nod *nodNou)
{
sfarsit++;
nod[sfarsit] = nodNou;
}
int numarAparitii()
{
return nod[inceput]->numarAparitii;
}
bool esteGoala()
{
return inceput > sfarsit;
}
Nod *scoate()
{
Nod *deIntors = nod[inceput];
inceput++;
return deIntors;
}
bool areUnSingurElement()
{
return inceput == sfarsit;
}
};
Nod *nodInitial(int numarAparitii, int indice)
{
Nod *nodNou = new Nod;
nodNou->numarAparitii = numarAparitii;
nodNou->indice = indice;
nodNou->stanga = NULL;
nodNou->dreapta = NULL;
return nodNou;
}
Coada coadaNoduriInitiale;
Coada coadaNoduriInterne;
Nod *celMaiMicNod()
{
if(coadaNoduriInterne.esteGoala())
return coadaNoduriInitiale.scoate();
else if(coadaNoduriInitiale.esteGoala())
return coadaNoduriInterne.scoate();
else if(coadaNoduriInitiale.numarAparitii() < coadaNoduriInterne.numarAparitii())
return coadaNoduriInitiale.scoate();
else
return coadaNoduriInterne.scoate();
}
long long lungimeMinima;
Nod *nodIntern()
{
Nod *nodNou = new Nod;
nodNou->stanga = celMaiMicNod();
nodNou->dreapta = celMaiMicNod();
nodNou->numarAparitii = nodNou->stanga->numarAparitii + nodNou->dreapta->numarAparitii;
lungimeMinima += nodNou->numarAparitii;
return nodNou;
}
void construiesteNoduriInterne()
{
while(!coadaNoduriInitiale.esteGoala() || !coadaNoduriInterne.areUnSingurElement())
coadaNoduriInterne.adauga(nodIntern());
}
const int numarMaximSimboluri = 1000000;
int lungimeCod[numarMaximSimboluri];
long long cod[numarMaximSimboluri];
void parcurgereInAdancime(Nod *radacina, int adancime, long long codZecimal)
{
if(radacina->stanga != NULL)
{
parcurgereInAdancime(radacina->stanga, adancime+1, codZecimal*2);
parcurgereInAdancime(radacina->dreapta, adancime+1, codZecimal*2+1);
return;
}
lungimeCod[radacina->indice] = adancime;
cod[radacina->indice] = codZecimal;
}
int main()
{
int numarSimboluri;
ifstream fin("huffman.in");
fin >> numarSimboluri;
coadaNoduriInitiale.initializeaza();
for(int i=0; i<numarSimboluri; i++)
{
int numarAparitii;
fin >> numarAparitii;
coadaNoduriInitiale.adauga(nodInitial(numarAparitii, i));
}
coadaNoduriInterne.initializeaza();
construiesteNoduriInterne();
parcurgereInAdancime(coadaNoduriInterne.scoate(), 0, 0);
ofstream fout("huffman.out");
fout << lungimeMinima << '\n';
for(int i=0; i<numarSimboluri; i++)
fout << lungimeCod[i] << ' ' << cod[i] << '\n';
return 0;
}