Cod sursa(job #2293357)

Utilizator CristyXtremeSimion Cristian CristyXtreme Data 30 noiembrie 2018 21:53:55
Problema Sortare prin comparare Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.31 kb
//  Heapsort cu Min-Heap
#include <stdio.h>

using namespace std;

void interschimba(int &a, int &b) {
    int aux = a;
    a = b;
    b = aux;
}

void jos(int pos, int *heap, int dim_heap) {
    while (true) {
        // daca nu are fii inseamna ca e pe pozitia corecta (avand in vedere ca valoarea de unde a venit era mai mica)
        if (pos * 2 > dim_heap)
            return;
        if (pos * 2 == dim_heap) { // are doar un fiu
            if (heap[pos] > heap[pos * 2]) {
                interschimba(heap[pos], heap[pos * 2]);
                pos *= 2;
            }
            else
                return;
        }
        else { // daca a ajuns pana aici inseamna ca are 2 fii
            int min_fiu_pos = pos * 2; // presupunem ca fiul stang e mai mic
            if (heap[pos * 2] > heap[pos * 2 + 1])
                min_fiu_pos++;  // al doilea fiu este cel cu care trebuie sa schimbam (min_fiu_pos++ echivalent cu min_fiu_pos = pos * 2 + 1)
            if (heap[pos] > heap[min_fiu_pos]) {
                interschimba(heap[pos], heap[min_fiu_pos]);
                pos = min_fiu_pos;
            }
            else
                return;
        }
    }
}

// transforma vectorul intr-un vector "heap" tragand fiecare element in jos
// incepem de la jumatate fiindca de la n/2 la n sunt doar frunze, deci daca le tragem in jos nu o sa facem de fapt nimic
void heapify(int *heap, int dim_heap) {
    int start = dim_heap / 2;
    while (start > 0) {
        jos(start, heap, dim_heap);
        start--;
    }
}

int main() {
	freopen("algsort.in", "r", stdin);
	freopen("algsort.out", "w", stdout);
	int n;
	scanf("%d", &n);
	int v[500001];
	for (int i = 1; i <= n; i++)
        scanf("%d", &v[i]);
    heapify(v, n);
    for (int i = 2; i <= n; i++) {
        printf("%i ", v[1]);                // primul element din heap va fi mereu cel mai mic element, deci il scriem
        interschimba(v[1], v[n - i + 2]);   // interschimbam primul element cu o pozitie pe care nu o vom mai accesa in viitor, efectiv stergandu-l
        jos(1, v, n - i + 1);               // interschimbarea a stricat partial ordinea heap-ului, asa ca ducem primul element (care inainte era o frunza) in noul loc, aducand noul element minim in prima pozitie
    }
    printf("%i ", v[1]);
	return 0;
}