Pagini recente » Cod sursa (job #72462) | Cod sursa (job #676465) | Cod sursa (job #1033059) | Cod sursa (job #3148958) | Cod sursa (job #381398)
Cod sursa(job #381398)
/*
*MinHeapuri binomiale
*/
#include <cstdio>
#include <cassert>
#include <queue>
#include <fstream>
using namespace std;
typedef unsigned char byte;
struct nod
{
int key;
byte ord;//ordinul arborelui
nod *fiu;//cel mai din stanga fiu
nod *frate;//fratele din dreapta
nod *tata;
};
nod *R;
void uneste(nod* &A,nod *B)//unesc arborii binomiali A si B a.i radacina sa devina A
{
assert(A->ord == B->ord);
assert(!A->tata && !B->tata);
B->frate=A->fiu;
A->fiu=B;
B->tata=A;
A->ord++;
}
nod *fa_nod(int key)//creez un arbore binomial de ordinul 0 cu key-ul respectiv
{
nod *p=new nod;
p->key=key;
p->ord=0;
p->fiu=p->frate=p->tata=NULL;
return p;
}
void BF(nod *H)
{
queue< pair<nod*,int> > Q;
nod *p;
for (p=H;p;p=p->frate) Q.push(make_pair(p,1));
int k=1;
for (;!Q.empty();Q.pop())
{
if (Q.front().second > k) printf("\n"),k++;
printf("%d",Q.front().first->key);
if (k>1) printf("(%d)",Q.front().first->tata->key);
printf(" ");
p=Q.front().first->fiu;
for (;p;p=p->frate) Q.push( make_pair(p,k+1));
}
printf("\n---------------------------------------------\n");
}
void merge(nod* &H1,nod *H2)//unesc heapurile binomiale H1 si H2 in H1
{
if (!H2) return;
nod *H=NULL,*t,*p=H1,*q=H2,*ret;
while (p || q)
if (!q || (p && p->ord < q->ord))
{
if (!H) H=t=p;
else
{
t->frate=p;
t=p;
}
p=p->frate;
}
else
{
if (!H) H=t=q;
else
{
t->frate=q;
t=q;
}
q=q->frate;
}
nod *prev=NULL;
p=H;q=H->frate;
while (q)
if (p->ord < q->ord || (q->frate && q->frate->ord == p->ord))
{
prev=p;
p=p->frate;
q=q->frate;
}
else
if (p->key >= q->key)
{
uneste(q,p);
if (!prev) H=q;
else prev->frate=q;
p=q;
q=q->frate;
}
else
{
ret=q->frate;
uneste(p,q);
p->frate=ret;
if (!prev) H=p;
else prev->frate=p;
q=p->frate;
}
H1=H;
}
void add(nod* &H,int x)//adaug elementul x in heapul H
{
nod *h=fa_nod(x);
merge(H,h);
}
int Extract_Min(nod* &H)
{
nod *t,*h;
int min=H->key;
for (t=H;t;t=t->frate)
if (t->key <= min) min=t->key,h=t;
if (h!=H)
{
for (t=H;t->frate != h;t=t->frate);
t->frate=h->frate;
}
else H=h->frate;
t=h->fiu;
delete h;
h=NULL;
while (t)
{
t->tata=NULL;
nod *ret=t->frate;
t->frate=h;
h=t;
t=ret;
}
merge(H,h);
return min;
}
nod *H;
int main()
{
int N,i,x;
ifstream fin("algsort.in");
fin>>N;
for (i=1;i<=N;++i) {fin>>x;add(H,x);}
ofstream fout("algsort.out");
for (i=1;i<=N;++i) fout<<Extract_Min(H)<<' ';
return 0;
}