Cod sursa(job #381398)

Utilizator mihai_floreaFlorea Mihai Alexandru mihai_florea Data 10 ianuarie 2010 15:11:26
Problema Sortare prin comparare Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
/*
 *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;
}