Pagini recente » Cod sursa (job #722486) | Cod sursa (job #2848048) | Cod sursa (job #3247386) | Cod sursa (job #2302298) | Cod sursa (job #2077512)
#include <iostream>
#include <fstream>
using namespace std;
struct Nod
{
long long numarAparitii;
long long fiu[2];
};
const long long numarMaximSimboluri = 1000000;
Nod nod[2*numarMaximSimboluri - 1];
struct Coada
{
long long indice[numarMaximSimboluri];
long long inceput;
long long sfarsit;
void initializeaza()
{
inceput = 0;
sfarsit = -1;
}
void adauga(int i)
{
sfarsit++;
indice[sfarsit] = i;
}
bool esteGoala()
{
return inceput > sfarsit;
}
long long i()
{
return indice[inceput];
}
long long scoate()
{
long long deIntors = indice[inceput];
inceput++;
return deIntors;
}
bool areUnSingurElement()
{
return inceput == sfarsit;
}
};
Coada coadaNoduriInitiale;
Coada coadaNoduriInterne;
long long celMaiMicNod()
{
if(coadaNoduriInterne.esteGoala())
return coadaNoduriInitiale.scoate();
else if(coadaNoduriInitiale.esteGoala())
return coadaNoduriInterne.scoate();
else if(nod[coadaNoduriInitiale.i()].numarAparitii < nod[coadaNoduriInterne.i()].numarAparitii)
return coadaNoduriInitiale.scoate();
else
return coadaNoduriInterne.scoate();
}
long long lungimeMinima;
long long nodIntern(long long &numarNoduri)
{
Nod nodNou;
nodNou.fiu[0] = celMaiMicNod();
nodNou.fiu[1] = celMaiMicNod();
cout << nod[nodNou.fiu[0]].numarAparitii << ' ' << nod[nodNou.fiu[1]].numarAparitii << '\n';
nodNou.numarAparitii = nod[nodNou.fiu[0]].numarAparitii + nod[nodNou.fiu[1]].numarAparitii;
lungimeMinima += nodNou.numarAparitii;
nod[numarNoduri] = nodNou;
long long deIntors = numarNoduri;
numarNoduri++;
return deIntors;
}
void construiesteNoduriInterne(long long &numarNoduri)
{
while(coadaNoduriInitiale.inceput + coadaNoduriInterne.inceput <= coadaNoduriInitiale.sfarsit + coadaNoduriInterne.sfarsit)
coadaNoduriInterne.adauga(nodIntern(numarNoduri));
}
long long lungimeCod[numarMaximSimboluri];
long long cod[numarMaximSimboluri];
void parcurgereInAdancime(Nod nod[], long long i, long long adancime, long long codZecimal)
{
if(nod[i].fiu[0] != -1)
{
parcurgereInAdancime(nod, nod[i].fiu[0], adancime+1, codZecimal*2);
parcurgereInAdancime(nod, nod[i].fiu[1], adancime+1, codZecimal*2+1);
return;
}
lungimeCod[i] = adancime;
cod[i] = codZecimal;
}
int main()
{
long long numarSimboluri;
ifstream fin("huffman.in");
fin >> numarSimboluri;
coadaNoduriInitiale.initializeaza();
for(long long i=0; i<numarSimboluri; i++)
{
fin >> nod[i].numarAparitii;
nod[i].fiu[0] = -1;
nod[i].fiu[1] = -1;
coadaNoduriInitiale.adauga(i);
}
coadaNoduriInterne.initializeaza();
long long numarNoduri = numarSimboluri;
construiesteNoduriInterne(numarNoduri);
cout<<lungimeMinima;
parcurgereInAdancime(nod, coadaNoduriInterne.scoate(), 0, 0);
ofstream fout("huffman.out");
fout << lungimeMinima << '\n';
for(long long i=0; i<numarSimboluri; i++)
fout << lungimeCod[i] << ' ' << cod[i] << '\n';
return 0;
}