Cod sursa(job #381401)

Utilizator mihai_floreaFlorea Mihai Alexandru mihai_florea Data 10 ianuarie 2010 15:15:53
Problema Sortare prin comparare Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
/*
 *MinHeapuri binomiale fara sa retin si pe tactu
 */
#include <cstdio>
#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 *R;
void uneste(nod* &A,nod *B)//unesc arborii binomiali A si B a.i radacina sa devina A
{
	B->frate=A->fiu;
	A->fiu=B;
	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=NULL;
	return p;
}
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)
	{
		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;
}