Cod sursa(job #2383043)

Utilizator RobertLicaRobert Lica RobertLica Data 18 martie 2019 23:53:40
Problema Sortare prin comparare Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 7.55 kb
//#include "skipList.h"

//#ifndef __NODURI_H__
//#define __NODURI_H__

#include <iostream>
#include <fstream>

#define INITIAL 5

//#include "nodes.h"
#include <random>
template <typename T>
struct Node {
    T id, time, points;
    Node<T> *up;
    Node<T> *right;
    Node<T> *down;
    Node<T> *left;

    Node(T id, T time, T points) {
        this->id = id;
        this->time = time;
        this->points = points;
        up = nullptr;
        right = nullptr;
        down = nullptr;
        left = nullptr;
    }

    Node(T id, T time, T points, Node<T> *up_, Node<T> *right_,
            Node<T> *down_, Node<T> *left_) {
        this->id = id;
        this->time = time;
        this->points = points;
        up = up_;
        right = right_;
        down = down_;
        left = left_;
    }
};

//#endif // __NODURI_H__


//#ifndef __SKIPLIST_H__
//#define __SKIPLIST_H__


template <typename T>
void insertToLeft(Node<T> *nou, Node<T> *p);

template <typename T>
class Skiplist{
    int noLeyers;
    int maximLeyers;
    Node<T> **leyers;

public:
    Skiplist() {
        noLeyers = 1;
        maximLeyers = INITIAL;
        leyers = new Node<T>*[INITIAL];
        for (int i = 0; i < INITIAL; ++i) leyers[i] = nullptr;
        Node<T> *head = new Node<T>(-1, -1, -1);
        leyers[0] = head;
    }

    ~Skiplist() {
        while (noLeyers--) {
            Node<T> *p = leyers[noLeyers];
            Node<T> *next;
            while (p) {
                next = p->right;
                delete p;
                p = next;
            }
        }
        delete[] leyers;
    }


    void addNode(T id, T time, T points) {
        Node<T> *nou = new Node<T>(id, time, points);
        if (leyers[0]->right) {
            insertSmart(nou);
        } else {
            leyers[0]->right = nou;
            nou->left = leyers[0];
        }
        goUp(nou, 1);
    }

private:
    void insertSmart(Node<T> *nou) {
        int height = noLeyers - 1;
        Node<T> *p = leyers[height]->right;
        while (height > 0) {
            if (nou->points > p->points) {
                //std::cout << "caz 1\n";
                if (p->right) {
                    p = p->right;
                } else {
                    p = p->down;
                    height--;
                }
            } else if (nou->points < p->points) {
                //std::cout << "caz 2 | height: " << height << "\n";
                if (p != leyers[height]) {
                    //std::cout << "e diferit aici la cazul 2\n";
                    p = p->left->down->right;
                    //std::cout << "aici e segfault\n";
                    height--;
                } else {
                    //std::cout << "aparent nu i diferit la cazul 2";
                    p = p->down;
                    height--;
                }
            } else {
                //std::cout << "caz 3\n";
                p = p->down;
                height--;
            }
        }
        // Acum am ajuns pe ultimul nivel aproape de unde tre sa bagam valoarea
        if (nou->points == p->points) {
            insertToLeft(nou, p);
        } else if (nou->points > p->points) {
            while (p->right) {
                if (nou->points <= p->points) {
                    insertToLeft(nou, p);
                    break;
                }
                p = p->right;
            }
            if (p->left != nou) {
                if (nou->points == p->points) {
                    insertToLeft(nou, p);
                } else if (nou->points > p->points) {
                    nou->left = p;
                    p->right = nou;
                } else {
                    insertToLeft(nou, p);
                }
            }
        } else if (nou->points < p->points) {
            //std::cout << "s a intamplat si ";
            /*if (leyers[height] == p->left) {
                std::cout << "N am gresit\n";
            } else {
                std:: cout << "AM gresit\n";
            }*/
            insertToLeft(nou, p);
        }
    }

    void goUp(Node<T> *nou, int height) {
        std::random_device rd;
        if (rd() % 2) {
            //std::cout << "New Leyer :> " << "niveluri: " << noLeyers << " | current height: " << height << "\n";
            if (noLeyers == height) {
                noLeyers++;
                if (noLeyers == maximLeyers) {
                    Node<T> **nouleyers = new Node<T>*[maximLeyers + INITIAL];
                    for (int i = 0; i < maximLeyers; ++i) {
                        nouleyers[i] = leyers[i];
                    }
                    delete[] leyers;
                    leyers = nouleyers;
                    maximLeyers += INITIAL;
                }
                Node<T> *head = new Node<T>(-1, -1, -1);
                leyers[noLeyers - 1] = head;
                leyers[noLeyers - 2]->up = leyers[noLeyers - 1];
                leyers[noLeyers - 1]->down = leyers[noLeyers - 2];
            }
            //std::cout << "leftUp\n";
            Node<T> *leftUp = findUpperLeft(nou, height);
            //std::cout << "rightUp\n";
            Node<T> *rightUp = findUpperRightFromLeftUp(leftUp);
            //std::cout << "nouUp\n";
            Node<T> *nouUp = new Node<T>(nou->id, nou->time, nou->points, nullptr, rightUp, nou, leftUp);
            if (leftUp) leftUp->right = nouUp;
            if (rightUp) rightUp->left = nouUp;
            nou->up = nouUp;
            goUp(nouUp, height + 1);
        }
    }

    Node<T>* findUpperLeft(Node<T> *nou, int height) {
        Node<T> *p = nou->left;
        if (p == leyers[height - 1]) {
            return leyers[height];
        }
        while (p != leyers[height - 1]) {
            if (p->up) {
                return p->up;
            }
            p = p->left;
        }
        return leyers[height];
    }

    Node<T>* findUpperRightFromLeftUp(Node<T> *leftUp) {
        if (leftUp)
            return leftUp->right;
        else {
            std::cout << "era null boss";
            return nullptr;
        }
    }

public:
    template <typename U>
    friend void printInfoarena(const Skiplist<U>& skp);

    template <typename U>
    friend std::ostream& operator<<(std::ostream& os, Skiplist<U>& skp);
};


template <typename T>
void printInfoarena(const Skiplist<T>& skp) {
    Node<T> *p = skp.leyers[0]->right;
    while (p) {
        std::cout << p->points << " ";
        p = p->right;
    }
}

template <typename T>
void insertToLeft(Node<T> *nou, Node<T> *p) {
    Node<T> *q = p->left;
    q->right = nou;
    nou->left = q;
    p->left = nou;
    nou->right = p;
}


template <typename T>
std::ostream& operator<<(std::ostream& os, Skiplist<T>& skp) {
    Node<T> *it;
    for (int i = skp.noLeyers - 1; i >= 0; --i) {
        it = skp.leyers[i]->right;
        os << "[-1,-1,-1]";
        if (it) os <<  "<->";
        while (it) {
            os << "[" << it->id << "," << it->time << "," << it->points << "]";
            if (it->right) {
                os << " <-> ";
            }
            it = it->right;
        }
        os << "\n";
    }
    return os;
}

//#endif // __SKIPLIST_H__



int main() {

    Skiplist<int> skp;

    //int id, time, points;
    int n, infoarena = 0;
    std::cin >> n;

    while (n--) {
        std::cin >> infoarena;
        skp.addNode(0, 0, infoarena);
        //std::cout << skp << "\n";
    }

    printInfoarena(skp);
    return 0;
}