Cod sursa(job #2075852)

Utilizator dariusdariusMarian Darius dariusdarius Data 25 noiembrie 2017 19:01:39
Problema Sortare prin comparare Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.96 kb
#include <fstream>
#include <vector>

class Heap {
private:
    std::vector< std::pair<int, int> > h;  /// structura de heap in sine
    std::vector<int> poz; /// pozitia unui element, in ordinea inserarii

    int Parent(const int &index) const {
        return (index - 1) / 2;
    }
    int LeftSon(const int &index) const {
        return 2 * index + 1;
    }
    int RightSon(const int &index) const {
        return 2 * index + 2;
    }
    bool HasLeftSon(const int &index) const {
        return 2 * index + 1 < (int)h.size();
    }
    bool HasRightSon(const int &index) const {
        return 2 * index + 2 < (int)h.size();
    }
    bool IsLeaf(const int &index) const {
        return !HasLeftSon(index);
    }

    int GetKey(const int &index) const {
        return h[index].first;
    }
    int GetIndex(const int &index) const {
        return h[index].second;
    }

    void SwapNodes(const int &index1, const int &index2) {
        poz[GetIndex(index1)] = index2;
        poz[GetIndex(index2)] = index1;
        std::swap(h[index1], h[index2]);
    }

    void Sift(int index) {
        while (index > 0 && GetKey(index) < GetKey(Parent(index))) {
            SwapNodes(index, Parent(index));
            index = Parent(index);
        }
    }

    void Percolate(int index) {
        while (!IsLeaf(index)) {
            int son_with_lowest_key = LeftSon(index);
            int son_lowest_key = GetKey(son_with_lowest_key);
            if (HasRightSon(index)) {
                int right_son_key = GetKey(RightSon(index));
                if (right_son_key < son_lowest_key) {
                    son_with_lowest_key = RightSon(index);
                    son_lowest_key = right_son_key;
                }
            }
            if (son_lowest_key < GetKey(index)) {
                SwapNodes(index, son_with_lowest_key);
                index = son_with_lowest_key;
            } else {
                break;
            }
        }
    }
public:
    Heap() {}

    void Push(int key) {
        int index = poz.size();
        h.push_back({key, index});
        poz.push_back(h.size() - 1);

        Sift(h.size() - 1);
    }

    int Pop() {
        int ret = h[0].first;

        SwapNodes(0, h.size() - 1);
        poz[ret] = -1;
        h.pop_back();

        // Percolate down the node from the root
        Percolate(0);

        return ret;
    }

    int Min() {
        return h[0].first;
    }

    void RemoveKth(int k) {
        int p = poz[k];
        SwapNodes(p, h.size() - 1);
        h.pop_back();

        Sift(p);
        Percolate(p);
    }
};

int main()
{
    std::ifstream cin("algsort.in");
    std::ofstream cout("algsort.out");
    Heap h;
    int n;
    cin >> n;
    for (int x, i = 1; i <= n; ++ i) {
        cin >> x;
        h.Push(x);
    }
    for (int i = 1; i <= n; ++ i) {
        cout << h.Pop() << (i == n ? '\n' : ' ');
    }
    return 0;
}