Algoritmi e strutture dati
Salve. Purtroppo ho ricevuto un voto basso (20) all'esame di algoritmi e strutture dati e naturalmente ho rifiutato. Sono consapevole che la funzione listLastNode(list) è un disastro ma non so davvero come implementarla. Qualcuno potrebbe aiutarmi? Grazie mille
Qui c'è l'esercizio con le strutture apposite
https://onlinegdb.com/CKS9ooQJJ
Qui c'è l'esercizio con le strutture apposite
https://onlinegdb.com/CKS9ooQJJ
/* * La segreteria di una Universita' deve riorganizzare alcuni elenchi di studenti * tra cui elenco1 (un BST) ed elenco2 (una HT). In ciascuna struttura uno studente * è rappresentato dalla matricola (campo chiave), dal nome e dal cognome. * * Si dovrà realizzare un programma che sposti tutti gli studenti con matricola * dispari in elenco1 e tutti gli studenti con matricola pari in elenco2 rimuovendo * gli eventuali duplicati. Inoltre, si dovranno copiare in elenco3 (una lista) * tutti gli studenti di elenco2 (dopo le operazioni suddette). * Infine, bisognera' eliminare lo studente con la matricola piu' bassa in elenco3 * e stampare lo studente con la matricola piu' alta. * * Per realizzare tale programma occorre sviluppare le seguenti funzioni. * * 1) HTtoBSTodd(ht, bst): funzione ITERATIVA che copia da ht a bst tutti gli studenti * con matricola dispari, rimuovendoli da ht. * Se uno studente di ht gia' esiste in bst esso non verra' * duplicato (ma verra' comunque rimosso da ht). * * 2) BSTtoHTeven(bst, ht): funzione RICORSIVA che copia da bst a ht tutti gli * studenti con matricola pari rimuovendoli da bst. Se uno studente di bst * gia' esiste in ht esso non verrà duplicato (ma verra' comunque rimosso da bst). * * 3) HTtoList(ht, list): funzione ITERATIVA che copia tutti gli studenti * di ht in list. * * 4) deleteMinList(list): funzione che elimina lo studente con la matricola piu' bassa. * * 5) listLastNode(list): funzione RICORSIVA che restituisce il riferimento (puntatore) * all'ultimo elemento della lista (per poi stamparne il contenuto nella funzione main). */ #include <stdio.h> #include <string.h> #include "THT.h" #include "TBST.h" #include "TArray.h" #include "TInfo.h" #include "TList.h" int isEven(TKey num){ if(num%2==0) return 1; else return 0; } TBST HTtoBSTodd(THT* ht, TBST bst) { for (int i = 0; i < ht->n_bucket; ++i) for (TNode* node = ht->bucket[i]; node != NULL; node = node->link) if (isEven(node->info.key) == 0) { if (BSTsearch(bst, node->info) == NULL) bst = BSTinsert(bst, node->info); HTdelete(ht, node->info.key); } return bst; } TBST BSTtoHTeven(TBST bst, THT* ht) { if (bst != NULL) { bst->left = BSTtoHTeven(bst->left, ht); bst->right = BSTtoHTeven(bst->right, ht); if (isEven(bst->info.key) == 1) { HTinsert(ht, bst->info.key, bst->info.value); bst = BSTdelete(bst, bst->info); } } return bst; } TList HTtoList(THT *ht, TList list) { TNode* node = nodeCreate(list->info); for (int i = 0; i < ht->n_bucket; ++i) for (TNode* node = ht->bucket[i]; node != NULL; node = node->link) HTdelete(ht, node->info.key); list = listInsert(list, node->info); return list; } TList deleteMinList(TList list) { TNode* curr = list; TNode* prev; TInfo min, max; /* Ricerca degli elementi da cancellare */ while(curr != NULL) { if(infoGreater(curr->info, min) && infoLess(curr->info, max)) { prev = curr; list = listDelete(list, curr->info); curr = prev->link; } else curr = curr->link; } return list; } TNode* listLastNode(TList l){ TNode* node; /* Caso Base */ if(l == NULL) { return 0; } /* Divide et Impera (+ combina) */ if(node->right == NULL){ return node->left; } // Divide et Impera (+ combina) if(node->right == NULL){ return node->left; } node->right = listLastNode(node->right); return l; } int main() { TBST elenco1 = BSTcreate(); elenco1 = BSTinsert(elenco1, (TInfo) {1321, "Mario", "Rossi"}); elenco1 = BSTinsert(elenco1, (TInfo) {2372, "Antonio", "Bianchi"}); elenco1 = BSTinsert(elenco1, (TInfo) {3432, "Lucia", "Verdi"}); elenco1 = BSTinsert(elenco1, (TInfo) {4223, "Camilla", "Neri"}); elenco1 = BSTinsert(elenco1, (TInfo) {1445, "Aldo", "Giallini"}); elenco1 = BSTinsert(elenco1, (TInfo) {2234, "Carlo", "Aranci"}); elenco1 = BSTinsert(elenco1, (TInfo) {1238, "Maria", "Scarlatti"}); elenco1 = BSTinsert(elenco1, (TInfo) {6643, "Luigi", "Turchesi"}); elenco1 = BSTinsert(elenco1, (TInfo) {1111, "Giovanni", "Argento"}); THT *elenco2 = HTcreate(5); HTinsert(elenco2, 3357, (TValue) {"Nicola", "Grigetti"}); HTinsert(elenco2, 7675, (TValue) {"Costanza", "Violetti"}); HTinsert(elenco2, 4222, (TValue) {"Filippa", "Azzurri"}); HTinsert(elenco2, 1445, (TValue) {"Aldo", "Giallini"}); HTinsert(elenco2, 3233, (TValue) {"Anna", "Indaco"}); HTinsert(elenco2, 3321, (TValue) {"Luigi", "Rosi"}); HTinsert(elenco2, 1111, (TValue) {"Giovanni", "Argento"}); HTinsert(elenco2, 3432, (TValue) {"Lucia", "Verdi"}); HTinsert(elenco2, 1238, (TValue) {"Maria", "Scarlatti"}); printf("Studenti in elenco1 (BST):\n"); BSTprint(elenco1); printf("\nStudenti in elenco2 (HT):\n"); HTprint(elenco2); elenco1 = HTtoBSTodd(elenco2, elenco1); elenco1 = BSTtoHTeven(elenco1, elenco2); printf("\nStudenti in elenco1 (BST) dopo lo spostamento\n(solo matricole dispari senza duplicati):\n"); BSTprint(elenco1); printf("\nStudenti in elenco2 (HT) dopo lo spostamento\n(solo matricole pari senza duplicati):\n"); HTprint(elenco2); TList elenco3 = listCreate(); elenco3 = HTtoList(elenco2, elenco3); printf("\nStudenti in elenco3 (Lista)\n"); listPrint(elenco3); elenco3 = deleteMinList(elenco3); printf("\nStudenti in elenco3 (Lista)\n(tutti quelli di elenco2 tranne la matricola piu' bassa)\n"); listPrint(elenco3); printf("\nUltimo studente in elenco3 (Lista)\n(matricola piu' alta):\n"); TNode* last_node = listLastNode(elenco3); infoPrint(last_node->info); BSTdestroy(elenco1); HTdestroy(elenco2); listDestroy(elenco3); return 0; }
Risposte
Perché usi left e right se hai a che fare con una lista? Insomma era sufficiente qualcosa come questo:
Detto questo, in HTtoBSTodd non è appropriato chiamare [inline]HTdelete(ht, node->info.key);[/inline] mentre stai iterando sul bucket. È inoltre inefficiente dato che sai esattamente dove si trova l'elemento che vuoi eliminare.
Stessa cosa per BSTtoHTeven.
HTtoList è anche peggio perché cancelli un elemento di cui possiedi un puntatore e che ancora non hai copiato altrove.
Anche deleteMinList è sbagliato e non capisco come mai stai cercando massimo e minimo e cancelli il valore all'interno del ciclo e non dopo.
TNode* listLastNode(TList l){ if(l == NULL || l->link == NULL) { return l; } return listLastNode(l->link); }
Detto questo, in HTtoBSTodd non è appropriato chiamare [inline]HTdelete(ht, node->info.key);[/inline] mentre stai iterando sul bucket. È inoltre inefficiente dato che sai esattamente dove si trova l'elemento che vuoi eliminare.
Stessa cosa per BSTtoHTeven.
HTtoList è anche peggio perché cancelli un elemento di cui possiedi un puntatore e che ancora non hai copiato altrove.
Anche deleteMinList è sbagliato e non capisco come mai stai cercando massimo e minimo e cancelli il valore all'interno del ciclo e non dopo.
https://onlinegdb.com/ojQuuoyage Ho aggiornato il codice ma lo stesso non funziona
/* * La segreteria di una Universita' deve riorganizzare alcuni elenchi di studenti * tra cui elenco1 (un BST) ed elenco2 (una HT). In ciascuna struttura uno studente * è rappresentato dalla matricola (campo chiave), dal nome e dal cognome. * * Si dovrà realizzare un programma che sposti tutti gli studenti con matricola * dispari in elenco1 e tutti gli studenti con matricola pari in elenco2 rimuovendo * gli eventuali duplicati. Inoltre, si dovranno copiare in elenco3 (una lista) * tutti gli studenti di elenco2 (dopo le operazioni suddette). * Infine, bisognera' eliminare lo studente con la matricola piu' bassa in elenco3 * e stampare lo studente con la matricola piu' alta. * * Per realizzare tale programma occorre sviluppare le seguenti funzioni. * * 1) HTtoBSTodd(ht, bst): funzione ITERATIVA che copia da ht a bst tutti gli studenti * con matricola dispari, rimuovendoli da ht. * Se uno studente di ht gia' esiste in bst esso non verra' * duplicato (ma verra' comunque rimosso da ht). * * 2) BSTtoHTeven(bst, ht): funzione RICORSIVA che copia da bst a ht tutti gli * studenti con matricola pari rimuovendoli da bst. Se uno studente di bst * gia' esiste in ht esso non verrà duplicato (ma verra' comunque rimosso da bst). * * 3) HTtoList(ht, list): funzione ITERATIVA che copia tutti gli studenti * di ht in list. * * 4) deleteMinList(list): funzione che elimina lo studente con la matricola piu' bassa. * * 5) listLastNode(list): funzione RICORSIVA che restituisce il riferimento (puntatore) * all'ultimo elemento della lista (per poi stamparne il contenuto nella funzione main). */ #include <stdio.h> #include <string.h> #include "THT.h" #include "TBST.h" #include "TArray.h" #include "TInfo.h" #include "TList.h" int isEven(TKey num){ if(num%2==0) return 1; else return 0; } TBST HTtoBSTodd(THT* ht, TBST bst) { for (int i = 0; i < ht->n_bucket; ++i) for (TNode* node = ht->bucket[i]; node != NULL; node = node->link) if (isEven(node->info.key) == 0) { if (BSTsearch(bst, node->info) == NULL) bst = BSTinsert(bst, node->info); } return bst; } TBST BSTtoHTeven(TBST bst, THT* ht) { if (bst != NULL) { bst->left = BSTtoHTeven(bst->left, ht); bst->right = BSTtoHTeven(bst->right, ht); if (isEven(bst->info.key) == 1) { HTinsert(ht, bst->info.key, bst->info.value); } } return bst; } TList HTtoList(THT *ht, TList list) { TNode* node2 = nodeCreate(list->info); for (int i = 0; i < ht->n_bucket; ++i) for (TNode* node = ht->bucket[i]; node != NULL; node = node->link) if (listSearch(list, node2->info) == NULL) list = listInsert(list, node2->info); HTdelete(ht, node2->info.key); return list; } TList deleteMinList(TList list) { TNode* curr = list; TNode* prev; TInfo min, max; /* Ricerca degli elementi da cancellare */ while(curr != NULL) { if(infoGreater(curr->info, min) && infoLess(curr->info, max)) { prev = curr; list = listDelete(list, curr->info); curr = prev->link; } else curr = curr->link; } return list; } TNode* listLastNode(TList l){ if(l == NULL || l->link == NULL) { return l; } return listLastNode(l->link); } int main() { TBST elenco1 = BSTcreate(); elenco1 = BSTinsert(elenco1, (TInfo) {1321, "Mario", "Rossi"}); elenco1 = BSTinsert(elenco1, (TInfo) {2372, "Antonio", "Bianchi"}); elenco1 = BSTinsert(elenco1, (TInfo) {3432, "Lucia", "Verdi"}); elenco1 = BSTinsert(elenco1, (TInfo) {4223, "Camilla", "Neri"}); elenco1 = BSTinsert(elenco1, (TInfo) {1445, "Aldo", "Giallini"}); elenco1 = BSTinsert(elenco1, (TInfo) {2234, "Carlo", "Aranci"}); elenco1 = BSTinsert(elenco1, (TInfo) {1238, "Maria", "Scarlatti"}); elenco1 = BSTinsert(elenco1, (TInfo) {6643, "Luigi", "Turchesi"}); elenco1 = BSTinsert(elenco1, (TInfo) {1111, "Giovanni", "Argento"}); THT *elenco2 = HTcreate(5); HTinsert(elenco2, 3357, (TValue) {"Nicola", "Grigetti"}); HTinsert(elenco2, 7675, (TValue) {"Costanza", "Violetti"}); HTinsert(elenco2, 4222, (TValue) {"Filippa", "Azzurri"}); HTinsert(elenco2, 1445, (TValue) {"Aldo", "Giallini"}); HTinsert(elenco2, 3233, (TValue) {"Anna", "Indaco"}); HTinsert(elenco2, 3321, (TValue) {"Luigi", "Rosi"}); HTinsert(elenco2, 1111, (TValue) {"Giovanni", "Argento"}); HTinsert(elenco2, 3432, (TValue) {"Lucia", "Verdi"}); HTinsert(elenco2, 1238, (TValue) {"Maria", "Scarlatti"}); printf("Studenti in elenco1 (BST):\n"); BSTprint(elenco1); printf("\nStudenti in elenco2 (HT):\n"); HTprint(elenco2); elenco1 = HTtoBSTodd(elenco2, elenco1); elenco1 = BSTtoHTeven(elenco1, elenco2); printf("\nStudenti in elenco1 (BST) dopo lo spostamento\n(solo matricole dispari senza duplicati):\n"); BSTprint(elenco1); printf("\nStudenti in elenco2 (HT) dopo lo spostamento\n(solo matricole pari senza duplicati):\n"); HTprint(elenco2); TList elenco3 = listCreate(); elenco3 = HTtoList(elenco2, elenco3); printf("\nStudenti in elenco3 (Lista)\n"); listPrint(elenco3); elenco3 = deleteMinList(elenco3); printf("\nStudenti in elenco3 (Lista)\n(tutti quelli di elenco2 tranne la matricola piu' bassa)\n"); listPrint(elenco3); printf("\nUltimo studente in elenco3 (Lista)\n(matricola piu' alta):\n"); TNode* last_node = listLastNode(elenco3); infoPrint(last_node->info); BSTdestroy(elenco1); HTdestroy(elenco2); listDestroy(elenco3); return 0; }
No, gli elementi devi eliminarli, ma non puoi farlo mentre stai iterando. Provo a commentarti la prima versione di [inline]HTtoBSTodd[/inline]:
La parte dell'inserimento nell'albero è OK. Analizziamo quindi la parte che elimina gli elementi dispari (ho rinominato la funzione per meglio descrivere che cosa ci si aspetta che faccia), ovvero:
[inline]HTdelete[/inline] ricalcola [inline]i[/inline] da [inline]node->info.key[/inline] usando la funzione di hash, quindi prova ad eliminare [inline]node->info.key[/inline] da [inline]ht->bucket[/inline]. Ovvero prova ad eliminare [inline]node[/inline]. In sostanza, quel codice è equivalente a:
che ovviamente crasha dato che stai cercando di accedere ad una memoria dopo aver chiamato free su quella memoria. Prova a pensare a come puoi modificare il ciclo per evitare il problema.
TBST HTtoBSTodd(THT* ht, TBST bst) { for (int i = 0; i < ht->n_bucket; ++i) for (TNode* node = ht->bucket[i]; node != NULL; node = node->link) if (isEven(node->info.key) == 0) { if (BSTsearch(bst, node->info) == NULL) bst = BSTinsert(bst, node->info); HTdelete(ht, node->info.key); } return bst; }
La parte dell'inserimento nell'albero è OK. Analizziamo quindi la parte che elimina gli elementi dispari (ho rinominato la funzione per meglio descrivere che cosa ci si aspetta che faccia), ovvero:
void HTRemoveOdd(THT* ht) { for (int i = 0; i < ht->n_bucket; ++i) for (TNode* node = ht->bucket[i]; node != NULL; node = node->link) if (isEven(node->info.key) == 0) { HTdelete(ht, node->info.key); } }
[inline]HTdelete[/inline] ricalcola [inline]i[/inline] da [inline]node->info.key[/inline] usando la funzione di hash, quindi prova ad eliminare [inline]node->info.key[/inline] da [inline]ht->bucket[/inline]. Ovvero prova ad eliminare [inline]node[/inline]. In sostanza, quel codice è equivalente a:
void HTRemoveOdd(THT* ht) { for (int i = 0; i < ht->n_bucket; ++i) TNode** prev = &ht->bucket[i]; for (TNode* node = ht->bucket[i]; node != NULL; node = node->link) if (isEven(node->info.key) == 0) { *prev = node->link; free(node); } else { *prev = &(node->link); } }
che ovviamente crasha dato che stai cercando di accedere ad una memoria dopo aver chiamato free su quella memoria. Prova a pensare a come puoi modificare il ciclo per evitare il problema.
https://onlinegdb.com/qjhT53z_84 --> codice aggiornato
I primi quattro punti del main vengono stampati il problema si preesenta dalla riga 152 che non mi stampa i studenti in elenco3
I primi quattro punti del main vengono stampati il problema si preesenta dalla riga 152 che non mi stampa i studenti in elenco3
/* * La segreteria di una Universita' deve riorganizzare alcuni elenchi di studenti * tra cui elenco1 (un BST) ed elenco2 (una HT). In ciascuna struttura uno studente * è rappresentato dalla matricola (campo chiave), dal nome e dal cognome. * * Si dovrà realizzare un programma che sposti tutti gli studenti con matricola * dispari in elenco1 e tutti gli studenti con matricola pari in elenco2 rimuovendo * gli eventuali duplicati. Inoltre, si dovranno copiare in elenco3 (una lista) * tutti gli studenti di elenco2 (dopo le operazioni suddette). * Infine, bisognera' eliminare lo studente con la matricola piu' bassa in elenco3 * e stampare lo studente con la matricola piu' alta. * * Per realizzare tale programma occorre sviluppare le seguenti funzioni. * * 1) HTtoBSTodd(ht, bst): funzione ITERATIVA che copia da ht a bst tutti gli studenti * con matricola dispari, rimuovendoli da ht. * Se uno studente di ht gia' esiste in bst esso non verra' * duplicato (ma verra' comunque rimosso da ht). * * 2) BSTtoHTeven(bst, ht): funzione RICORSIVA che copia da bst a ht tutti gli * studenti con matricola pari rimuovendoli da bst. Se uno studente di bst * gia' esiste in ht esso non verrà duplicato (ma verra' comunque rimosso da bst). * * 3) HTtoList(ht, list): funzione ITERATIVA che copia tutti gli studenti * di ht in list. * * 4) deleteMinList(list): funzione che elimina lo studente con la matricola piu' bassa. * * 5) listLastNode(list): funzione RICORSIVA che restituisce il riferimento (puntatore) * all'ultimo elemento della lista (per poi stamparne il contenuto nella funzione main). */ #include <stdio.h> #include <string.h> #include "THT.h" #include "TBST.h" #include "TArray.h" #include "TInfo.h" #include "TList.h" int isEven(TKey num){ if(num%2==0) return 1; else return 0; } TBST HTtoBSTodd(THT* ht, TBST bst) { for (int i = 0; i < ht->n_bucket; ++i) for (TNode* node = ht->bucket[i]; node != NULL; node = node->link) if (isEven(node->info.key) == 0) { if (BSTsearch(bst, node->info) == NULL){ bst = BSTinsert(bst, node->info); HTdelete(ht, node->info.key); } } return bst; } TBST BSTtoHTeven(TBST bst, THT* ht) { if (bst != NULL) { bst->left = BSTtoHTeven(bst->left, ht); bst->right = BSTtoHTeven(bst->right, ht); if (isEven(bst->info.key) == 1) { HTinsert(ht, bst->info.key, bst->info.value); bst = BSTdelete(bst, bst->info); } } return bst; } TList HTtoList(THT *ht, TList list) { TNode* node2 = nodeCreate(list->info); for (int i = 0; i < ht->n_bucket; ++i) for (TNode* node = ht->bucket[i]; node != NULL; node = node->link) if (listSearch(list, node2->info) == NULL) list = listInsert(list, node2->info); HTdelete(ht, node2->info.key); return list; } TList deleteMinList(TList list) { TNode* curr = list; TNode* prev; TInfo min; /* Ricerca degli elementi da cancellare */ while(curr != NULL) { if(infoLess(curr->info, min)) { prev = curr; list = listDelete(list, curr->info); curr = prev->link; } else curr = curr->link; } return list; } TNode* listLastNode(TList l){ if(l == NULL || l->link == NULL) { return l; } return listLastNode(l->link); } int main() { TBST elenco1 = BSTcreate(); elenco1 = BSTinsert(elenco1, (TInfo) {1321, "Mario", "Rossi"}); elenco1 = BSTinsert(elenco1, (TInfo) {2372, "Antonio", "Bianchi"}); elenco1 = BSTinsert(elenco1, (TInfo) {3432, "Lucia", "Verdi"}); elenco1 = BSTinsert(elenco1, (TInfo) {4223, "Camilla", "Neri"}); elenco1 = BSTinsert(elenco1, (TInfo) {1445, "Aldo", "Giallini"}); elenco1 = BSTinsert(elenco1, (TInfo) {2234, "Carlo", "Aranci"}); elenco1 = BSTinsert(elenco1, (TInfo) {1238, "Maria", "Scarlatti"}); elenco1 = BSTinsert(elenco1, (TInfo) {6643, "Luigi", "Turchesi"}); elenco1 = BSTinsert(elenco1, (TInfo) {1111, "Giovanni", "Argento"}); THT *elenco2 = HTcreate(5); HTinsert(elenco2, 3357, (TValue) {"Nicola", "Grigetti"}); HTinsert(elenco2, 7675, (TValue) {"Costanza", "Violetti"}); HTinsert(elenco2, 4222, (TValue) {"Filippa", "Azzurri"}); HTinsert(elenco2, 1445, (TValue) {"Aldo", "Giallini"}); HTinsert(elenco2, 3233, (TValue) {"Anna", "Indaco"}); HTinsert(elenco2, 3321, (TValue) {"Luigi", "Rosi"}); HTinsert(elenco2, 1111, (TValue) {"Giovanni", "Argento"}); HTinsert(elenco2, 3432, (TValue) {"Lucia", "Verdi"}); HTinsert(elenco2, 1238, (TValue) {"Maria", "Scarlatti"}); printf("Studenti in elenco1 (BST):\n"); BSTprint(elenco1); printf("\nStudenti in elenco2 (HT):\n"); HTprint(elenco2); elenco1 = HTtoBSTodd(elenco2, elenco1); elenco1 = BSTtoHTeven(elenco1, elenco2); printf("\nStudenti in elenco1 (BST) dopo lo spostamento\n(solo matricole dispari senza duplicati):\n"); BSTprint(elenco1); printf("\nStudenti in elenco2 (HT) dopo lo spostamento\n(solo matricole pari senza duplicati):\n"); HTprint(elenco2); TList elenco3 = listCreate(); elenco3 = HTtoList(elenco2, elenco3); printf("\nStudenti in elenco3 (Lista)\n"); listPrint(elenco3); elenco3 = deleteMinList(elenco3); printf("\nStudenti in elenco3 (Lista)\n(tutti quelli di elenco2 tranne la matricola piu' bassa)\n"); listPrint(elenco3); printf("\nUltimo studente in elenco3 (Lista)\n(matricola piu' alta):\n"); TNode* last_node = listLastNode(elenco3); infoPrint(last_node->info); BSTdestroy(elenco1); HTdestroy(elenco2); listDestroy(elenco3); return 0; }
Stati continuando a fare lo stesso errore. Detto questo, il minimo di una lista ordinata in ordine crescente non è altro che il primo elemento, quindi il tuo codice fa operazioni inutili. Nota che [inline]min[/inline] non è inizializzata.
Per le prime due funzioni se metto HTDelete e BSTdelete al di fuori del ciclo non funzionano. Per quanto riguarda l'altra funzione non saprei cosa fare
Il problema è chiamare [inline]node->link[/inline] dopo aver fatto [inline]free(node)[/inline], quindi ti basta chiamarlo prima.
Chiamare [inline]HTdelete[/inline] è un po' uno spreco computazionale, ma almeno non stai accedendo ad una memoria deallocata. Di fatto dato che accedi subito dopo, senza alcun multithreading e che non stai runnando il codice con un AddressSanitizer, il codice funziona lo stesso, ma è comunque una cattiva pratica.
TBST HTtoBSTodd(THT* ht, TBST bst) { for (int i = 0; i < ht->n_bucket; ++i) { for (TNode* node = ht->bucket[i]; node != NULL; ) { TNode* temp = node; node = node->link; if (isEven(temp->info.key) == 0) { if (BSTsearch(bst, temp->info) == NULL) { bst = BSTinsert(bst, temp->info); HTdelete(ht, temp->info.key); } } } } return bst; }oppure
TBST HTtoBSTodd(THT* ht, TBST bst) { for (int i = 0; i < ht->n_bucket; ++i) { TNode* next = NULL; for (TNode* node = ht->bucket[i]; node != NULL; node = next ) { next = node->link; if (isEven(node->info.key) == 0) { if (BSTsearch(bst, node->info) == NULL) { bst = BSTinsert(bst, node->info); HTdelete(ht, node->info.key); } } } } return bst; }
Chiamare [inline]HTdelete[/inline] è un po' uno spreco computazionale, ma almeno non stai accedendo ad una memoria deallocata. Di fatto dato che accedi subito dopo, senza alcun multithreading e che non stai runnando il codice con un AddressSanitizer, il codice funziona lo stesso, ma è comunque una cattiva pratica.
mentre per le altre funzioni cosa dovrei cambiare?
BSTtoHTeven è ok, non stai accedendo a nulla dopo averlo eliminato.
HTtoList si fa uguale a HTtoBSTodd.
Per quanto riguarda deleteMinList ti ho già detto: List è una lista ordinata in ordine crescente.
HTtoList si fa uguale a HTtoBSTodd.
Per quanto riguarda deleteMinList ti ho già detto: List è una lista ordinata in ordine crescente.
Funziona perfettamente. Grazie mille per avermi aiutato a capire
https://onlinegdb.com/5BKiNUjEI -> codice aggiornato

https://onlinegdb.com/5BKiNUjEI -> codice aggiornato
/* * La segreteria di una Universita' deve riorganizzare alcuni elenchi di studenti * tra cui elenco1 (un BST) ed elenco2 (una HT). In ciascuna struttura uno studente * è rappresentato dalla matricola (campo chiave), dal nome e dal cognome. * * Si dovrà realizzare un programma che sposti tutti gli studenti con matricola * dispari in elenco1 e tutti gli studenti con matricola pari in elenco2 rimuovendo * gli eventuali duplicati. Inoltre, si dovranno copiare in elenco3 (una lista) * tutti gli studenti di elenco2 (dopo le operazioni suddette). * Infine, bisognera' eliminare lo studente con la matricola piu' bassa in elenco3 * e stampare lo studente con la matricola piu' alta. * * Per realizzare tale programma occorre sviluppare le seguenti funzioni. * * 1) HTtoBSTodd(ht, bst): funzione ITERATIVA che copia da ht a bst tutti gli studenti * con matricola dispari, rimuovendoli da ht. * Se uno studente di ht gia' esiste in bst esso non verra' * duplicato (ma verra' comunque rimosso da ht). * * 2) BSTtoHTeven(bst, ht): funzione RICORSIVA che copia da bst a ht tutti gli * studenti con matricola pari rimuovendoli da bst. Se uno studente di bst * gia' esiste in ht esso non verrà duplicato (ma verra' comunque rimosso da bst). * * 3) HTtoList(ht, list): funzione ITERATIVA che copia tutti gli studenti * di ht in list. * * 4) deleteMinList(list): funzione che elimina lo studente con la matricola piu' bassa. * * 5) listLastNode(list): funzione RICORSIVA che restituisce il riferimento (puntatore) * all'ultimo elemento della lista (per poi stamparne il contenuto nella funzione main). */ #include <stdio.h> #include <string.h> #include "THT.h" #include "TBST.h" #include "TArray.h" #include "TInfo.h" #include "TList.h" int isEven(TKey num){ if(num%2==0) return 1; else return 0; } TBST HTtoBSTodd(THT* ht, TBST bst) { for (int i = 0; i < ht->n_bucket; ++i) { for (TNode* node = ht->bucket[i]; node != NULL;) { TNode* temp = node; node = node->link; if (isEven(temp->info.key) == 0) { if (BSTsearch(bst, temp->info) == NULL) { bst = BSTinsert(bst, temp->info); HTdelete(ht, temp->info.key); } } } } return bst; } TBST BSTtoHTeven(TBST bst, THT* ht) { if (bst != NULL) { bst->left = BSTtoHTeven(bst->left, ht); bst->right = BSTtoHTeven(bst->right, ht); if (isEven(bst->info.key) == 1) { HTinsert(ht, bst->info.key, bst->info.value); bst = BSTdelete(bst, bst->info); } } return bst; } TList HTtoList(THT* ht, TList list) { for (int i = 0; i < ht->n_bucket; ++i) { for (TNode* node = ht->bucket[i]; node != NULL;) { TNode* temp = node; node = node->link; if (listSearch(list, temp->info) == NULL) { list = listInsert(list, temp->info); HTdelete(ht, temp->info.key); } } } return list; } TList deleteMinList(TList list) { TNode* curr = list; TNode* prev; TInfo min; /* Ricerca degli elementi da cancellare */ while(curr != NULL) { if(infoGreater(curr->info, min)) { prev = curr; list = listDelete(list, curr->info); curr = prev->link; } else curr = curr->link; } return list; } TNode* listLastNode(TList l){ if(l == NULL || l->link == NULL) { return l; } return listLastNode(l->link); } int main() { TBST elenco1 = BSTcreate(); elenco1 = BSTinsert(elenco1, (TInfo) {1321, "Mario", "Rossi"}); elenco1 = BSTinsert(elenco1, (TInfo) {2372, "Antonio", "Bianchi"}); elenco1 = BSTinsert(elenco1, (TInfo) {3432, "Lucia", "Verdi"}); elenco1 = BSTinsert(elenco1, (TInfo) {4223, "Camilla", "Neri"}); elenco1 = BSTinsert(elenco1, (TInfo) {1445, "Aldo", "Giallini"}); elenco1 = BSTinsert(elenco1, (TInfo) {2234, "Carlo", "Aranci"}); elenco1 = BSTinsert(elenco1, (TInfo) {1238, "Maria", "Scarlatti"}); elenco1 = BSTinsert(elenco1, (TInfo) {6643, "Luigi", "Turchesi"}); elenco1 = BSTinsert(elenco1, (TInfo) {1111, "Giovanni", "Argento"}); THT *elenco2 = HTcreate(5); HTinsert(elenco2, 3357, (TValue) {"Nicola", "Grigetti"}); HTinsert(elenco2, 7675, (TValue) {"Costanza", "Violetti"}); HTinsert(elenco2, 4222, (TValue) {"Filippa", "Azzurri"}); HTinsert(elenco2, 1445, (TValue) {"Aldo", "Giallini"}); HTinsert(elenco2, 3233, (TValue) {"Anna", "Indaco"}); HTinsert(elenco2, 3321, (TValue) {"Luigi", "Rosi"}); HTinsert(elenco2, 1111, (TValue) {"Giovanni", "Argento"}); HTinsert(elenco2, 3432, (TValue) {"Lucia", "Verdi"}); HTinsert(elenco2, 1238, (TValue) {"Maria", "Scarlatti"}); printf("Studenti in elenco1 (BST):\n"); BSTprint(elenco1); printf("\nStudenti in elenco2 (HT):\n"); HTprint(elenco2); elenco1 = HTtoBSTodd(elenco2, elenco1); elenco1 = BSTtoHTeven(elenco1, elenco2); printf("\nStudenti in elenco1 (BST) dopo lo spostamento\n(solo matricole dispari senza duplicati):\n"); BSTprint(elenco1); printf("\nStudenti in elenco2 (HT) dopo lo spostamento\n(solo matricole pari senza duplicati):\n"); HTprint(elenco2); TList elenco3 = listCreate(); elenco3 = HTtoList(elenco2, elenco3); printf("\nStudenti in elenco3 (Lista)\n"); listPrint(elenco3); elenco3 = deleteMinList(elenco3); printf("\nStudenti in elenco3 (Lista)\n(tutti quelli di elenco2 tranne la matricola piu' bassa)\n"); listPrint(elenco3); printf("\nUltimo studente in elenco3 (Lista)\n(matricola piu' alta):\n"); TNode* last_node = listLastNode(elenco3); infoPrint(last_node->info); BSTdestroy(elenco1); HTdestroy(elenco2); listDestroy(elenco3); return 0; }
La mia impressione è che tu stia scrivendo i programmi copiando e incollando soluzioni qua e là, invece dovresti farlo come se stessi scrivendo la ricetta di un ciambellone. Insomma ti devi chiarire i passaggi e poi scriverli nel linguaggio appropriato.
In questo codice usi [inline]min[/inline] senza averla inizializzata.
o anche
In questo codice usi [inline]min[/inline] senza averla inizializzata.
TList deleteMinList(TList list) { TNode* curr = list; TNode* prev; TInfo min; /* Ricerca degli elementi da cancellare */ while(curr != NULL) { if(infoGreater(curr->info, min)) { prev = curr; list = listDelete(list, curr->info); curr = prev->link; } else curr = curr->link; } return list; }tra l'altro, non hai ascoltato il mio consiglio: TList è una lista ordinata. Quindi ti sarebbe bastato scrivere:
TList deleteMinList(TList list) { if ( list != NULL ) { list = listDelete(list, list->info); } return list; }
o anche
TList deleteMinList(TList list) { if ( list != NULL ) { TList temp = list; list = list->link; nodeDestroy(temp); } return list; }