Heap

di il
13 risposte

Heap

Ciao a tutti.
Sono nuovo e sano una vera chiavica nel programmare..... volevo chiedervi un parere circa gli heap.
ho scritto un codice, non sembra sbagliato ma l'outup non è consono al 100% alle mie esigenze.

Vi scrivo il codice:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
#define lenght 10


void heapyfy (int b[],int i);
void buildheap (int b[]);
int main(void)
{
int i;
int a[SIZE] ={4,1,3,2,16,9,10,14,8,7};
for (i=0;i<SIZE;i++)
printf("%3d\n",a);
printf("----------------------------------\n");


buildheap(a);
for (i=0;i<SIZE;i++)
printf("%3d\n",a);



return 0;
}
void heapyfy(int b[],int i)
{
int left, right,max;
left= 2*i+1;
right = 2*i+2;
int appoggio;
if (left<=SIZE && b[left]>b)
max=left;
else max=i;
if (right<=SIZE && b[right]>b[max])
max=right;


if (max != i)
{
appoggio=b;
b=b[max];
b[max]=appoggio;
heapyfy(b,max);
}

}

void buildheap(int b[])
{
int i;
for (i=(lenght-1)/2 ;i>=0;i--)
heapyfy(b,i);
}

La funzione heapyfy funziona bene, la funzione buildheap mi da un outupo quasi corretto, tranne che per 2 posizioni.

Mi sapete dire dove canno?


Grazie ancora e buona giornata

13 Risposte

  • Re: Heap

    Usa i tag code per favore.

    marco792005 ha scritto:


    La funzione heapyfy funziona bene, la funzione buildheap mi da un outupo quasi corretto, tranne che per 2 posizioni.
    Quali sono gli errori che hai.
  • Re: Heap

    quali sono gli errori che hai?
    praticamente 2 valori dell array non vengono posizionati in modo corretto , inoltre viene duplicato il valore 10 . Praticamente nell array di ritorno mi ritrovo due 10

    grazie ancora
  • Re: Heap

    
    void buildheap(int b[]){
       int i;
       for (i=(lenght/2)-1; i>=0; i--)
           heapyfy(b,i);
    }
    
    Prova a correggere così e vedi se funziona!
  • Re: Heap

    Prova a correggere così e vedi se funziona!
    Grazie per l'intervento.
    Ho provato, ma il risultato è il medesimo.
    d'altronde il valore di lenght è sempre lo stesso.
    L'output è il seguente:
    16
    14
    10
    8
    10
    9
    3
    2
    4
    7


    Non capisco veramente dove sta l'errore....

    grazie e buona giornata
  • Re: Heap

    
    void heapyfy(int b[], int i){
        int left, right, max;
        int appoggio;
    
        left= 2*i+1;
        right = 2*i+2;
    
        if (left < lenght && b[left]>b[i])
             max = left;
        else
            max = i;
    
        if (right < lenght && b[right]>b[max])
            max = right;
    
        if (max != i){
    	     appoggio=b[i];
            b[i]=b[max];
            b[max]=appoggio;
    	     heapyfy(b, max);
        }
        return;
    }
    
    Il problema è proprio la funzione heapyfy. Adesso dovrebbe funzionare correttamente.
  • Re: Heap

    Il problema è proprio la funzione heapyfy. Adesso dovrebbe funzionare correttamente.
    Grazie, così funziona. Solo che mi rimangono dei dubbi che ti chiedo se puoi, di chiarirmi:
    if (left < lenght && b[left]>b)


    nel tuo codice hai utiizzato il minore e non il minore uguale, sul testo che sto utilizzando nello pseudocodice viene usato il minore uguale, rieschi ha spiegarmi perchè col minore funziona e con il minore uguale no?

    if (max != i){
    appoggio=b;
    b=b[max];
    b[max]=appoggio;
    heapyfy(b, max);
    }
    return;


    l'omettere il return è un errore? il compilatore non mi da neanche dei warning.

    for (i=(lenght/2)-1; i>=0; i--)


    scrivere i=lenght/2-1 e scrivere i = (lenght-1)/2 è la stessa cosa vero?

    Grazie ancora.

    p.S. Riprenderò questo post quando studierò l'ordinamento heapsort. (sperando di trovare meno difficoltà)
  • Re: Heap

    if (left < lenght && b[left]>b)

    Funziona per valori solo minori perchè altrimenti andresti fuori range.

    l'omettere il return è un errore? il compilatore non mi da neanche dei warning.

    Se la funzione non deve ritornare valori come nel nostro caso, allora il return si può omettere.


    scrivere i=lenght/2-1 e scrivere i = (lenght-1)/2 è la stessa cosa vero?


    Puoi convincerti facendo prove numeriche che non sempre è la stessa cosa. Ad esempio prova a fare il calcolo per una cifra pari e poi ad una cifra dispari.
  • Re: Heap

    Funziona per valori solo minori perchè altrimenti andresti fuori range.
    Sei stato chiarissimo e per questo ti ringrazio.
    Aggiungo il codice necessario per effettuare l'heapsort.

    #include <stdio.h>
    #include <stdlib.h>
    #define SIZE 10
    #define lenght 10


    void heapyfy (int b[],int i);
    void buildheap (int b[]);
    void heapsort (int b[]);
    int main(void)
    {
    int i;
    int a[SIZE] ={4,1,3,2,16,9,10,14,8,7};
    for (i=0;i<SIZE;i++)
    printf("%3d\n",a);
    printf("----------------------------------\n");


    buildheap(a);
    for (i=0;i<SIZE;i++)
    printf("%3d\n",a);
    printf("--------------------------\n");

    heapsort(a);
    for(i=0;i<SIZE;i++)
    printf("%3d\n",a[1]);
    printf("--------------------------\n");


    return 0;
    }
    void heapyfy(int b[],int i)
    {
    int left, right,max;
    left= 2*i+1;
    right = 2*i+2;
    int appoggio;
    if (left<SIZE && b[left]>b)
    max=left;
    else max=i;
    if (right<SIZE && b[right]>b[max])
    max=right;


    if (max != i)
    {
    appoggio=b;
    b=b[max];
    b[max]=appoggio;
    heapyfy(b,max);
    }

    }

    void buildheap(int b[])
    {
    int i;
    for (i=(lenght/2)-1 ;i>=0;i--)
    heapyfy(b,i);
    }

    void heapsort (int b[])
    {
    buildheap(b);
    int i, appoggio,k;
    k=0;
    for (i=SIZE-1;i>1;i--)
    {
    appoggio=b;
    b=b[k];
    b[k]=appoggio;
    k++;
    }
    heapyfy (b,k);

    }

    Nell'output mi fa vedere solo una serie di dieci quattro.
    L'idea dell'algoritmo è:
    1) creo un heap
    2) creo due indici.
    3) mi posiziono all'ultima casella del mio array b[size-1]
    4) scambio il valore del punto 3 con il primo valore del mio array
    5) riapplico la propiretà dell'heap all'emento con indice k.

    Grazie ancora per l'aiuto

    Buona giornata
  • Re: Heap

    Scusami ma se non metti i tag code e indenti il codice, non riesco a leggerlo!
  • Re: Heap

    Scusami ma se non metti i tag code e indenti il codice, non riesco a leggerlo!
    hai ragione, ti chiedo scusa, provo ad utilizzare i tag code
    #include <stdio.h>
    #include <stdlib.h>
    #define SIZE 10
    #define lenght 10
    
    
    void heapyfy (int b[],int i);
    void buildheap (int b[]);
    void heapsort (int b[]);
    int main(void)
    {
    int i;
    int a[SIZE] ={4,1,3,2,16,9,10,14,8,7};
    for (i=0;i<SIZE;i++)
    printf("%3d\n",a[i]);
    printf("----------------------------------\n");
    
    
    buildheap(a);
    for (i=0;i<SIZE;i++)
    printf("%3d\n",a[i]);
    printf("--------------------------\n");
    
    heapsort(a);
    for(i=0;i<SIZE;i++)
    printf("%3d\n",a[1]);
    printf("--------------------------\n");
    
    
    return 0;
    }
    void heapyfy(int b[],int i)
    {
    int left, right,max;
    left= 2*i+1;
    right = 2*i+2;
    int appoggio;
    if (left<SIZE && b[left]>b[i])
    max=left;
    else max=i;
    if (right<SIZE && b[right]>b[max])
    max=right;
    
    
    if (max != i)
    {
    appoggio=b[i];
    b[i]=b[max];
    b[max]=appoggio;
    heapyfy(b,max);
    }
    
    }
    
    void buildheap(int b[])
    {
    int i;
    for (i=(lenght/2)-1 ;i>=0;i--)
    heapyfy(b,i);
    }
    
    void heapsort (int b[])
    {
        buildheap(b);
        int i, appoggio,k;
        k=0;
        for (i=SIZE-1;i>1;i--)
            {
                appoggio=b[i];
                b[i]=b[k];
                b[k]=appoggio;
                k++;
            }
        heapyfy (b,k);
    
    }
    
    abbiamo appurato che heapify e build heap funzionano, per terminare lo studio degli heap, mi manca solo l'ordinamento heapsort.

    Da quello che ho capito io (quindi molto poco:)) l'algoritmo deve seguire i seguenti passi:
    1) trasformo l'array in un heap
    2) creo 2 indici ed una variabile d'appoggio
    3) inizio il ciclo da size-1 elemento del mio array (cioè dall'ultimo), fino al secondo elemento ed ogni volta decremento il mio indice i ( quindi parto da 9 e arrivo a 1)
    4) scambio l'ultimo elemento b con il primo elemento b[k]
    5) incremento il mio k
    6) ripeto la costruzione del mio heap (con paramento k e chiaramente array b)

    Cosa ne pensi? ( il SIZE nella condizione del ciclo for mi sa che è cannato, ma come potrei fare?)

    Grazie ancora e scusami per gli orrori
  • Re: Heap

    Da quello che ho capito io (quindi molto poco:)) l'algoritmo deve seguire i seguenti passi:
    1) trasformo l'array in un heap
    2) scambi l'ultimo elemento con il primo
    3) ricostruisci l'heap a partire dal primo elemento ma con dimensione size-1

    la dimensione dell'heap è sempre minore fino ad avere il vettore ordinato.

    il problema è che hai dichiarato una variabile lenght che non puoi modificare, devi rivedere questa cosa, o trovare un'alternativa a questo; in modo l'heapyfy può operare sul vettore ridotto di una unità ad ogni iterazione.
  • Re: Heap

    il problema è che hai dichiarato una variabile lenght che non puoi modificare, devi rivedere questa cosa, o trovare un'alternativa a questo; in modo l'heapyfy può operare sul vettore ridotto di una unità ad ogni iterazione.
    Come sempre ti ringrazio per l'intervento.
    quindi il problema è in heapify che esegue l'heap tenendo sempre conto della lunghezza statica.
    A questo punto è un bel casino. Potrei creare una funzione hepefay2 controllato da un ciclo. Ad ogni interazione del ciclo diminuisco di un unità il mio array, poi eseguo l'heapify sull'array restante

    Hai qualche idea, giusto concettuale per indicarmi la strada migliore?

    grazie
  • Re: Heap

    Esattamente il problema è proprio in quella lenght.

    Io anzichè rivedere tutto cercherei di modificare le funzioni, passando lenght come parametro in modo da poter utilizzare lenght come variabile e non come costante, quindi modificabile.
Devi accedere o registrarti per scrivere nel forum
13 risposte