Cod sursa(job #2745063)

Utilizator anaop32Oprea Ana-Maria anaop32 Data 25 aprilie 2021 20:20:26
Problema Heapuri Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.83 kb
#include <fstream>
#include <vector>
#include <iostream>
using namespace std;

int nrOp, op;
vector<int> myHeap;
vector<int> temp;


void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

void heapify(vector<int> &heap, int i){
    int size = heap.size();
    int smallest = i;
    int l = (2*i) + 1; // left child
    int r = (2*i) + 2; // right child
    if (l < size && heap[l] < heap[smallest])
        smallest = l;
    if (r < size && heap[r] < heap[smallest])
        smallest = r;
    
    if (smallest != i){
        swap(heap[smallest], heap[i]);
        heapify(heap, smallest);
    }

}



void urca(vector<int> &heap, int poz){
    // pornesc cu ultima pozitie din vector
    // cat timp mai pot sa urc in heap
    while(poz){
        // tatal fata de nodul pozitie se afla la (poz-1)/2
        int tata = (poz - 1) / 2;
        // daca tatal este mai mare decat fiul atunci interchimb valorile
        if (heap[tata] > heap[poz]){
            // tatal vine in locul fiului si fiul in locul tatalui
            swap(heap[tata], heap[poz]);
            // noua pozitie din heap a elementului va fi pozitia veche a tatalui
            poz = tata;    
        }
        else
        // daca tatal este mai mic decat fiul atunci inseamna ca a ajuns la pozitia potrivita in heap
            break;
    }
}

void inserare(vector<int> &heap, int elem){
    // int size = v.size();
    // temp.push_back(elem);
    // if (size == 0)
    //     v.push_back(elem);
    // else{
    //     v.push_back(elem);
    //     for (int i = size / 2 - 1; i >= 0; i--){
    //         heapify(v, i);
    //     }
    // }
    heap.push_back(elem);
    temp.push_back(elem);
    urca(heap, heap.size() - 1);
}

void print_heap(){
    cout << "Heap:";
    for (int i = 0; i < myHeap.size(); i++)
        cout << myHeap[i] << " ";
    cout << endl;
}


void coboara(vector<int> &heap, int poz){
    if (poz * 2 + 1 >= heap.size())
        return;
    int tata = heap[poz];
    int fiu_stang = heap[poz*2 + 1];
    if ((poz * 2 + 2 == heap.size()) || (fiu_stang < heap[poz * 2 + 2])){
        if (fiu_stang < tata){
            swap(heap[poz], heap[poz * 2 + 1]);
            //cout << "stang" << endl;
            //print_heap();
            coboara(heap, poz * 2 + 1);
            return;
        }
        else{
            return;
        }
    }
    else{
            if (heap[poz * 2 + 2] < tata){
                print_heap();
                swap(heap[poz * 2 + 2], heap[poz]);
                //cout << "drept" << endl;
                //print_heap();
                coboara(heap, poz * 2 + 2);
                return;
            }
            else
                return;
        }
}

int gaseste(vector<int> &heap, int elem){
    for (int i = 0; i < heap.size(); i++)
        if (elem == heap[i])
            return i;
}


void elimina(vector<int> &heap, int poz){
    int elem = temp[poz - 1];
    int poz_in_heap = gaseste(heap, elem);
    //cout << "poz in heap al elem " << elem << " este " << poz_in_heap << endl;
    swap(heap[poz_in_heap], heap[heap.size() - 1]);
    heap.pop_back();
    //print_heap(); // pana aici e bine
    coboara(heap, poz_in_heap);
    urca(heap, poz_in_heap);
}

int peek(){
    return myHeap[0];
}



ifstream f("heapuri.in");
ofstream g("heapuri.out");

int main(){
    f >> nrOp;
    for (int i = 0; i < nrOp; i++){
        f >> op;
        switch (op){
            case 1: 
                    f >> op;
                    inserare(myHeap, op);
                    break;
            case 2:
                    f >> op;
                    elimina(myHeap, op);
                    break;
            case 3:
                    g << peek() << endl;
                    break;
        }
    }

    return 0;
}