Diferente pentru treapuri intre reviziile #18 si #19

Nu exista diferente intre titluri.

Diferente intre continut:

Heapurile şi arborii de căutare sunt uşor de implementat şi de înţeles, iar treapurile sunt o combinaţie a acestor două concepte. Astfel, e suficient să fie înţeles invariantul, după care implementarea unui treap se poate face cu uşurinţă în 20 de minute, fără antrenament. De obicei, la structuri ca arbori roşu negrii trebuie folosite serii de rotaţii stânga şi dreapta complexe şi analizate o mulţime de cazuri, pe când la treapuri facem doar câte o rotaţie stânga sau o rotaţie dreapta la fiecare pas al algoritmului. Ei nu sunt predaţi pentru că arborii roşu negrii sau AVL au demonstraţia că merg în $O(log N)$ şi sunt exemple didactice, dar treapurile deşi cu o demonstraţie mai grea sunt mult mai uşori de implementat şi poate şi puţin mai rapizi ca arborii AVL.
 
== code(cpp) |
#include <cstdio>
#include <algorithm>
    T *left, *right;
} *R, *nil;     // R radacina; nil arata un nod `gol`
void init(void)
void init(T* &R)
{
    srand(unsigned(time(0)));
    R = nil = new T();
        nil->left = nil->right = NULL;
}
T* rotleft(T *n)    // roteste fiul stang
void rotleft(T* &n)    // roteste fiul stang
{
    T *t = n->left;
    n->left = t->right, t->right = n;
    return t;       // noua radacina
    n = t;             // noua radacina
}
T* rotright(T *n)   // roteste fiul drept
void rotright(T* &n)   // roteste fiul drept
{
    T *t = n->right;
    n->right = t->left, t->left = n;
    return t;       // noua radacina
    n = t;             // noua radacina
}
T* balance(T *n)    // restabileste invariantul heapurilor
void balance(T* &n)    // restabileste invariantul heapurilor
{
    // balance() e apelat dupa un insert(), astfel doar cel mult unul din cei doi fii nu respecta invariantul heapurilor
    if (n->left->priority > n->priority)
        return rotleft(n);
 
    if (n->right->priority > n->priority)
        return rotright(n);
 
    return n;       // altfel nu face nimic
        rotleft(n);
    else if (n->right->priority > n->priority)
        rotright(n);
    // altfel nu face nimic
}
T* insert(T *n, int key)    // insereaza cheia 'key'
void insert(T* &n, int key)    // insereaza cheia 'key'
{
    if (n == nil)
    {
        n = new T();
        n->key = key, n->priority = rand() + 1,
                    n->left = n->right = nil;
        return n;
        return;
    }
    if (key < n->key)
        n->left = insert(n->left, key);
        insert(n->left, key);
    else if (key > n->key)
        n->right = insert(n->right, key);
        insert(n->right, key);
    // altfel e un duplicat; nu face nimic
    return balance(n);
    balance(n);
}
T* erase(T *n, int key)
void erase(T* &n, int key)
{
    if (n != nil)
    {
        if (key < n->key)
            n->left = erase(n->left, key);
        else if (key > n->key)
            n->right = erase(n->right, key);
        else {    // am gasit cheia
            // pune fiul cu prioritatea cea mai mare ca radacina in locul lui 'n'
            n = (n->left->priority > n->right->priority) ? rotleft(n) : rotright(n);
            if (n != nil)   // continua
                n = erase(n, key);
            else {
                delete n->left;
                n->left = NULL;
            }
    if (n == nil)   return ;
 
    if (key < n->key)
        erase(n->left, key);
    else if (key > n->key)
        erase(n->right, key);
    else {    // am gasit cheia
        // pune fiul cu prioritatea cea mai mare ca radacina in locul lui 'n'
        (n->left->priority > n->right->priority) ? rotleft(n) : rotright(n);
        if (n != nil)   // continua
            erase(n, key);
        else {
            delete n->left;
            n->left = NULL;
        }
    }
    return n;
}
T* empty(T *n)
void _empty(T* &n)
{
    if (n != nil)
    {
        empty(n->left), empty(n->right);
        _empty(n->left), _empty(n->right);
        delete n;
    }
    return nil;
}
 
void empty(T* &R)
{
    _empty(R), R = nil;
}
void print(T *n)
int main(void)
{
    init();
    init(R);
    // 1 s pentru a insera un milion de numere
    for (int i = 1 << 20; i >= 1; -- i)
        R = insert(R, i);
        insert(R, i);
    // 0.5 s pentru a sterge un milion de numere
    for (int i = 1; i <= 1 << 20; ++ i)
        R = erase(R, i);
 
    R = empty(R);
    for (int i = 1; i <= 1 << 20; ++ i) if (i < 11 || i > 25)
        erase(R, i);
    print(R);
    empty(R);
    print(R);
    return 0;
}
 
==

Nu exista diferente intre securitate.

Topicul de forum nu a fost schimbat.