Heap: code di priorità e HeapSort
In questa esercitazione si propone di realizzare la struttura
Heap in C++, onde implementare code di
priorità e l'algoritmo HeapSort.
Code di Prirità
Si consideri la sppecifica ADT delle code di priorità:
datatype PriorityQueue, Element;
constructors: EmptyQueue: PriorityQueue
Insert: PriorityQueue, Element -> PriorityQueue
ExtractMaximum: PriorityQueue -> PriorityQueue
observations:
Maximum: PriorityQueue -> Element
semantics:
Insert(S,x) = S unione {x}
Maximum(S) = x tale che Priorità(x) =
max {Priorità(y)| y in S}
ExtractMaximum(S) = S \ {Maximum(S)}
Si completi la realizzazione C++ proposta qui di seguito
scrivendo il codice mancante al posto dei puntini:
/* Heaps in C++: realizzazione non parametrica */
#include <iostream.h>
class Heap {
private:
int size; // dimensione del vettore heap_array
int heap_size; // prossima loc libera sul vettore
int* heap_array;
inline int Left (int i) {return 2*i + 1;} // i vettori in C/C++ cominciano da 0
inline int Right (int i) {return 2*i + 2;}
inline int Parent (int i) {return (i+1)/2 - 1;}
void Heapify (int i);
public:
Heap (int hs = 100); // hs heap dimensione max, default = 100
~Heap (); // distruttore (opera la deallocazione di uno heap)
void Insert (int e);
int Maximum ();
void ExtractMaximum ();
friend void ShowHeap (Heap* h); // friend: funzione che non e' membro della classe
// ma che puo' accedere ai suoi membri privati
};
Heap::Heap(int hs)
{
size = hs;
heap_size = 0;
heap_array = new int [hs];
}
Heap::~Heap()
{
delete [] heap_array; // sintassi per deallocare un vettore allocato con new
}
void exchange (int& n, int& m) // int& n e' analogo del Pascal var n
{
int temp;
temp = n;
n = m;
m = temp;
}
void Heap::Insert (int e)
{
int i, Parent_i; // i e' l'indice dell'elemento corrente (all'inizio una foglia)
// Parent_i = Parent(i) (per risparmiare chiamate e divisioni)
if (heap_size < size) {
...
// ShowHeap (this); sintassi da usare se si vuole una stampa dello heap qui per il debugging
} else cout << "Insert: heap is full\n"; // invia la stringa allo stream di output
}
int Heap::Maximum ()
{
...
}
void Heap::Heapify (int i)
// pre: Left(i), Right(i) sono radici di heap;
// post: i e' radice di uno heap
{
int largest, Left_i, Right_i;
// Left_i = Left(i), Right_i = Right(i) per ragioni di efficienza;
// largest e' usata per memorizzare l'indice del massimo
// tra heap_array[i], heap_array[Left_i], heap_array[Right_i]
...
}
void Heap::ExtractMaximum ()
{
...
}
/* funzione di utilita' */
void ShowHeap (Heap* h)
{
for (int i = 0; i < h->heap_size; i++)
cout << h->heap_array[i] << " ";
cout <<endl;
}
/* Main di prova */
int main (void)
{
cout << "Heap in C++" << endl;
Heap hp;
hp.Insert(16);
hp.Insert(7);
hp.Insert(14);
hp.Insert(1);
hp.Insert(8);
hp.Insert(10);
hp.Insert(3);
hp.Insert(2);
hp.Insert(4);
hp.Insert(15);
ShowHeap(&hp);
hp.ExtractMaximum();
ShowHeap(&hp);
return 0;
}
HeapSort
Si realizzi un'implementazione dell'algoritmo HeapSort in C++ modificato come segue:
dato un vettore, si utilizzi il metodo Insert per copiarne gli elementi in uno heap;
quindi si estraggano gli elementi dallo heap uno per volta, ridisponendoli nel
vettore a partire da destra.
Soluzione