Cod sursa(job #1816792)

Utilizator SlevySlevoaca Stefan-Gabriel Slevy Data 26 noiembrie 2016 21:50:50
Problema Sortare prin comparare Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.67 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#define NMAX 500005

using namespace std;

ifstream in("algsort.in");
ofstream out("algsort.out");

struct AVL_Node{
    int key;
    char height;
    AVL_Node* left;
    AVL_Node* right;
    int frecv;
};

int height_node(AVL_Node* Root)
{
    int l = (Root -> left != NULL) ? Root -> left -> height : 0;
    int r = (Root -> right != NULL) ? Root -> right -> height : 0;
    return 1 + max(l, r);
}

AVL_Node* LL_rotation(AVL_Node* &Root)
{
    AVL_Node* temp = Root -> left;
    Root -> left = temp -> right;
    temp -> right = Root;
    Root -> height = height_node(Root);
    temp -> height = height_node(temp);
    return temp;
}

AVL_Node* RR_rotation(AVL_Node* &Root)
{
    AVL_Node* temp = Root -> right;
    Root -> right = temp -> left;
    temp -> left = Root;
    Root -> height = height_node(Root);
    temp -> height = height_node(temp);
    return temp;
}

AVL_Node* LR_rotation(AVL_Node* &Root)
{
    Root -> left = RR_rotation(Root -> left);
    return LL_rotation(Root);
}

AVL_Node* RL_rotation(AVL_Node* &Root)
{
    Root -> right = LL_rotation(Root -> right);
    return RR_rotation(Root);
}

AVL_Node* balance(AVL_Node* &Root)
{
    char l = (Root -> left != NULL) ? Root -> left -> height : 0;
    char r = (Root -> right != NULL) ? Root -> right -> height : 0;
    Root -> height =  1 + max(l, r);
    char ll, rr;
    if (r > l + 1)
    {
        ll = (Root -> right -> left != NULL) ? Root -> right -> left -> height : 0;
        rr = (Root -> right -> right != NULL) ? Root -> right -> right -> height : 0;
        if (rr > ll)
            Root = RR_rotation(Root);
        else
            Root = RL_rotation(Root);
    }
    else if (l > r + 1)
    {
        ll = (Root -> left -> left != NULL) ? Root -> left -> left -> height : 0;
        rr = (Root -> left -> right != NULL) ? Root -> left -> right -> height : 0;
        if (ll > rr)
            Root = LL_rotation(Root);
        else
            Root = LR_rotation(Root);
    }
    return Root;
}

AVL_Node* insert(AVL_Node* &Root, int key)
{
    if (Root == NULL)
    {
        Root = new AVL_Node;
        Root -> key = key;
        Root -> left = NULL;
        Root -> right = NULL;
        Root -> height = 1;
        Root -> frecv = 1;
        return Root;
    }
    if (key < Root -> key)
        Root -> left = insert(Root -> left, key);
    else
        if (key > Root -> key)
            Root -> right = insert(Root -> right, key);
        else
            Root -> frecv++;
    return balance(Root);
}

int n, A[2 * NMAX / 3], B[NMAX / 3], l, r;
AVL_Node* AVL;

void Merge(int n, int m)
{
    int i = 1, j = 1;
    while (i <= n && j <= m)
    {
        if (A[i] < B[j])
            out << A[i++] << " ";
        else if (A[i] > B[j])
            out << B[j++] << " ";
        else
        {
            out << A[i] << " " << B[j] << " ";
            i++, j++;
        }
    }
    while (i <= n)
       out << A[i++] << " ";
    while (j <= m)
        out << B[j++] << " ";
}

void sort(AVL_Node* &Root)
{
    if (Root)
    {
        if (Root -> left != NULL)
            sort(Root -> left);
        for (int i = 1; i <= Root -> frecv; i++)
           B[++r] = Root -> key;
        if (Root -> right != NULL)
            sort(Root -> right);
    }
}

int main()
{
    in >> n;
    int x;
    for (int i = 1; i <= n / 3; i++)
    {
       in >> x;
       AVL = insert(AVL, x);
    }
    for (int i = n / 3 + 1; i <= n; i++)
        in >> A[++l];
    sort(AVL);
    std::sort(A + 1, A + l + 1);
    Merge(l, r);
    out.close();
    return 0;
}