Pagini recente » Monitorul de evaluare | Cod sursa (job #861953) | Cod sursa (job #2110165) | Cod sursa (job #1610752) | Cod sursa (job #1754359)
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
#define nmax 500003
ifstream in("algsort.in");
ofstream out("algsort.out");
/////////////////////////////////////////////////
////////
//////// HeapSort de mana(binary heap)
//////// folosim un max-heap
////////
////////////////////////////////////////////////
inline int ls(int i)//fiul stang al nodului i
{
return (2*i);
}
inline int rs(int i)//fiul drept al nodului i
{
return (2*i+1);
}
inline int father(int i)//tatal nodului i
{
return (i/2);
}
void heapify(int H[],int i,int n)//introduce elementul de pe pozitia i la locul lui in heap O(logn)
{
int posmin,pos = i;//p
while(true)//cat timp elementul nu a fost introdus la pozitia lui
{
posmin = pos;//presupunem ca a fost introdus
if ( ls(pos) <= n && H[ls(pos)]>H[posmin] )//daca avem nod in stanga si e mai mare
posmin = ls(pos);//o sa mutam valoarea in stanga
if ( rs(pos)<= n && H[rs(pos)]>H[posmin])//altfel in dreapta
posmin = rs(pos);
if ( pos != posmin )//daca presupunerea e gresita
{
swap(H[pos],H[posmin]);//ducem nodul mai jos
pos = posmin;
}
else
break;
}
}
void buildHeap(int H[],int n)//construim heapul O(n)
{
for(int i = n/2; i>0 ; i-- )//deoarece heapul e un arbore binar aproape compleet toate nodurile de pe ultimul nivel
heapify(H,i,n); //sunt heapuri deci luam toate nodurile de la un nivel mai sus si le punem la pozitia lor
}
void heapSort(int H[],int n)//O(nlogn)
{
buildHeap(H,n); //construim heapul
for( int i = n ; i > 0 ; i -- )
{
swap(H[1],H[i]);//scoatem maximul din heap
n--;//descrestem dimensiunea heapului
heapify(H,1,n);//si facem ca elementul din capul heapului sa fie la locul lui
}
}
/////////////////////////////////////////////////
////////
//////// HeapSort cu STL
//////// folosim un max-heap
////////
////////////////////////////////////////////////
void heapSortSTL(int * v, int n)
{
make_heap(v+1,v+n+1);//creeam heapul din arrayul v[1...n]
sort_heap(v+1,v+n+1);//sortam heapul din arrayul v[1...n]
//am putea sa bagam pe rand elemente cu push_heap si apoi sa dam sort_heap sau sa scoatem cu pop_heap si apoi sort_heap
}
/////////////////////////////////////////////////
////////
//////// Ternary-HeapSort de mana
//////// folosim un max-heap
////////
////////////////////////////////////////////////
inline int tls(int i)
{
return 3*i +1;
}
inline int tms(int i)
{
return 3*i +2;
}
inline int trs(int i)
{
return 3*i +3;
}
inline int tfather(int i)
{
return i/3;
}
void theapify(int *v, int i, int n)
{
int posmin,pos = i;
while(true)
{
posmin = pos;
if( tls(pos) <= n && v[tls(pos)] > v[posmin])
posmin = tls(pos);
if( tms(pos) <= n && v[tms(pos)] > v[posmin])
posmin = tms(pos);
if( trs(pos) <= n && v[trs(pos)] > v[posmin])
posmin = trs(pos);
if(posmin != pos)
{
swap(v[pos],v[posmin]);
pos = posmin;
}
else
break;
}
}
void tbuildHeap(int *v , int n)//construim heapul
{
for(int i = n/3; i >= 0 ; i--)//folosim proprietatea ca frunzele sunt toate numerele de la n/3 la n
theapify(v,i,n);
}
void theapSort(int *v, int n)//ternary heap foloseste un vector unde elementele sunt de la 0 la n-1 O(nlogn)
{
tbuildHeap(v,n-1);//construim max heapul
for(int i = n-1 ; i>= 0 ; i--)//eliminam cate un element
{
swap(v[0],v[i]);
theapify(v,0,i-1);
}
}
int main()
{
int n,i;
in >> n;
int heap[n+1];
for( i = 0 ; i < n ; i++)
in >> heap[i];
theapSort(heap,n);
for(int i = 0 ; i < n ; i ++)
out << heap[i] << " ";
return 0;
}