Cod sursa(job #1913726)

Utilizator radu_cebotariRadu Cebotari radu_cebotari Data 8 martie 2017 13:48:50
Problema Sortare prin comparare Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 5.58 kb
#include<fstream>
#include<iostream>
using namespace std;
ifstream in("algsort.in");
ofstream out("algsort.out");
const int NMAX = 500000;

template<class Tip>
class Heap{

    class Nod{
        public:
            Tip info;
            Nod *right;
            Nod *left;
            Nod *tata;
            int height;
            int nr_fii;
    };
    Nod *Root;
    Nod *Add_Key(Tip,Nod*,Nod*);
    int Get_Height(Nod*);
    int Get_Son_Nr(Nod*);
    bool is_complete(Nod*);
    void in_sus(Nod*);
    void in_jos(Nod*);
    Nod *Search_Last(Nod*);

public:
    Heap();
    void adauga(Tip);
    bool (*Compare)(Tip,Tip);
    Tip Front();
    void Extract();
    Tip *sortare(int,int);
};

template<class Tip>
Heap<Tip>::Heap(){
    Root = NULL;
}

template<class Tip>
bool Heap<Tip>::is_complete(typename Heap<Tip>::Nod *root)
{

    if((1<<(Get_Height(root))) - 1 == Get_Son_Nr(root) + 1)
        return true;
    return false;
}

template<class Tip>
int Heap<Tip>::Get_Height(typename Heap<Tip>::Nod *root)
{

    if(root == NULL)
        return 0;
    return root->height;
}

template<class Tip>
int Heap<Tip>::Get_Son_Nr(typename Heap<Tip>::Nod *root)
{

    if(root == NULL)
        return 0;
    return root->nr_fii;
}

template<class Tip>
void Heap<Tip>::in_sus(typename Heap<Tip>::Nod *root)
{

    if(root->tata == NULL)
        return;
    if(Compare(root->info,root->tata->info)){
        swap(root->info,root->tata->info);
        in_sus(root->tata);
    }
}

template<class Tip>
void Heap<Tip>::in_jos(typename Heap<Tip>::Nod *root){

    if(root == NULL)
        return;
    if(root->left && Compare(root->left->info,root->info) && root->right == NULL)
    {

        swap(root->left->info,root->info);
        in_jos(root->left);
        return;
    }
    if(root->right && Compare(root->right->info,root->info) && root->left == NULL)
    {

        swap(root->right->info,root->info);
        in_jos(root->right);
        return;
    }
    if(root->left && root->right && Compare(root->left->info,root->info) && Compare(root->left->info,root->right->info)){
        swap(root->left->info,root->info);
        in_jos(root->left);
        return;
    }
    if(root->right && Compare(root->right->info,root->info)){
        swap(root->right->info,root->info);
        in_jos(root->right);
        return;
    }

}

template<class Tip>
typename Heap<Tip>::Nod *Heap<Tip>::Add_Key(Tip info,typename Heap<Tip>::Nod *root,typename Heap<Tip>::Nod *Tata)
{

    if(root == NULL){
        typename Heap<Tip>::Nod *nou = new typename Heap<Tip>::Nod;
        nou->info = info;
        nou->height = 1;
        nou->right = NULL;
        nou->left = NULL;
        nou->nr_fii = 0;
        nou->tata = Tata;
        in_sus(nou);
        return nou;
    }
    if(is_complete(root->left) && is_complete(root->right)){
        if(Get_Height(root->left) == Get_Height(root->right))
            root->left = Add_Key(info,root->left,root);
        else
            root->right = Add_Key(info,root->right,root);
    }
    else if(is_complete(root->left))
        root->right = Add_Key(info,root->right,root);
    else
        root->left = Add_Key(info,root->left,root);
    if(root->left){
        root->height = max(root->height,Get_Height(root->left) + 1);
        root->nr_fii = Get_Son_Nr(root->left) + 1;
    }
    if(root->right){
        root->height = max(root->height,Get_Height(root->right) + 1);
        root->nr_fii += Get_Son_Nr(root->right) + 1;
    }
    return root;
}

template<class Tip>
void Heap<Tip>::adauga(Tip info)
{

    Root = Add_Key(info,Root,NULL);
}

template<class Tip>
Tip Heap<Tip>::Front()
{

    return Root->info;
}

template<class Tip>
typename Heap<Tip>::Nod *Heap<Tip>::Search_Last(typename Heap<Tip>::Nod *root)
{

    typename Heap<Tip>::Nod *node;
    if(root->right == NULL && root->left == NULL){
        root->height = 0;
        return root;
    }
    if(Get_Height(root->left) == Get_Height(root->right))
        node = Search_Last(root->right);
    else node = Search_Last(root->left);
    if(root->left){
        root->height = max(root->height,Get_Height(root->left) + 1);
        root->nr_fii = Get_Son_Nr(root->left) + 1;
    }
    if(root->right){
        root->height = max(root->height,Get_Height(root->right) + 1);
        root->nr_fii += Get_Son_Nr(root->right) + 1;
    }
    if(root->left && root->left->height == 0){
        root->left = NULL;
        root->nr_fii = 0;
        if(root->right)
            root->nr_fii = Get_Son_Nr(root->right) + 1;
    }
    if(root->right && root->right->height == 0){
        root->right = NULL;
        root->nr_fii = 0;
        if(root->left)
            root->nr_fii = Get_Son_Nr(root->left) + 1;
    }
    return node;
}

template<class Tip>
void Heap<Tip>::Extract()
{

    Nod* vechi = Search_Last(Root);
    Root->info = vechi->info;
    if(vechi == Root)
        Root = NULL;
    delete vechi;
    in_jos(Root);
}

template<class Tip>
Tip *Heap<Tip>::sortare(int left,int right)
{

    Tip *v = new Tip[right-left+2];
    for(int i = left ; i <= right ; ++i){
        v[i] = Front();
        Extract();
    }
    return v;
}

bool minim(int a,int b)
{

    return a < b;
}

int main()
{

    Heap<int> H;
    H.Compare = minim;
    int N;
    in>>N;
    int x;
    for(int i = 1 ; i <= N ; ++i){
        in>>x;
        H.adauga(x);
    }
    int *v = new int[N+2];
    v = H.sortare(1,N);
    for(int i = 1 ; i <= N ; ++i)
        out<<v[i]<<" ";
    return 0;
}