Cod sursa(job #1275186)

Utilizator nytr0gennytr0gen nytr0gen Data 24 noiembrie 2014 20:48:36
Problema Sortare prin comparare Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.99 kb
#include <cstdio>
#include <algorithm>
using namespace std;

struct node {
    int val, h;
    node *l, *r;
};

inline int geth(node *n) {
    if (n == NULL) return 0;

    int rh = 0;
    if (n->r != NULL) {
        rh = n->r->h;
    }

    int lh = 0;
    if (n->l != NULL) {
        lh = n->l->h;
    }

    return 1 + max(rh, lh);
}

inline int cmph(node *n, bool balance = 0) {
    if (n == NULL) return 0;

    int rh = 0;
    if (n->r != NULL) {
        rh = n->r->h;
    }

    int lh = 0;
    if (n->l != NULL) {
        lh = n->l->h;
    }

    // lh > rh + balance ? -1 : ((lh + balance < rh) ? 1 : 0)
    return (lh + balance < rh) - (lh > rh + balance);
}

node* rotleft(node *n) {
    node *t = n->r;
    n->r = t->l;
    t->l = n;

    n->h = geth(n);
    t->h = geth(t);

    return t;
}

node* rotright(node *n) {
    node *t = n->l;
    n->l = t->r;
    t->r = n;

    n->h = geth(n);
    t->h = geth(t);

    return t;
}

node* balance(node *n) {
    n->h = geth(n);

    // IF tree is right heavy
    if (cmph(n, 1) == 1) {
        // IF tree's right subtree is left heavy
        if (cmph(n->r) == -1) {
            //Perform Single Right rotation
            n->r = rotright(n->r);
        }

        // Perform Single Left rotation
        n = rotleft(n);
    }
    // ELSE IF tree is left heavy
    else if (cmph(n, 1) == -1) {
        // IF tree's left subtree is right heavy
        if (cmph(n->l) == 1) {
            // Perform Single Left rotation
            n->l = rotleft(n->l);
        }

        // Perform Single Right rotation
        n = rotright(n);
    }

    return n;
}

bool search(node *n, int val) {
    if (n == NULL)     return 0;
    if (n->val == val) return 1;

    if (val < n->val) {
        return search(n->l, val);
    } else {
        return search(n->r, val);
    }
}

node* insert(node *n, int val) {
    if (n == NULL) {
        n = new node;
        n->val = val; n->h = 1;
        n->l = n->r = NULL;

        return n;
    }

    if (val < n->val) {
        n->l = insert(n->l, val);
    } else {
        n->r = insert(n->r, val);
    }

    return balance(n);
}

node* erase(node *n, int val) {
    node *t;

    if (n == NULL) return n;
    if (n->val == val) {
        if (n->l == NULL || n->r == NULL) {
            t = n->l == NULL ? n->r : n->l;
            delete n;

            return t;
        } else {
            for (t = n->r; t->l != NULL; t = t->l);
            n->val = t->val;
            n->r   = erase(n->r, t->val);

            return balance(n);
        }
    }

    if (val < n->val) {
        n->l = erase(n->l, val);
    } else {
        n->r = erase(n->r, val);
    }

    return balance(n);
}

void show(node * n) {
    if (n->l != NULL) show(n->l);
    printf("%d ", n->val);
    if (n->r != NULL) show(n->r);
}

int main() {
    freopen("algsort.in", "r", stdin);
    freopen("algsort.out", "w", stdout);

    int N; scanf("%d", &N);

    int x;
    node *n = NULL;
    while (N--) {
        scanf("%d", &x);
        n = insert(n, x);
    }

    show(n);

    return 0;
}