Untitled

Choose a study mode

Play Quiz
Study Flashcards
Spaced Repetition
Chat to Lesson

Podcast

Play an AI-generated podcast conversation about this lesson
Download our mobile app to listen on the go
Get App

Questions and Answers

Quale tra le seguenti affermazioni descrive meglio il concetto di 'modularizzazione' nella progettazione del software?

  • Il processo di scrittura del codice sorgente in un linguaggio di programmazione specifico.
  • L'ottimizzazione delle prestazioni del software attraverso l'uso di algoritmi avanzati.
  • La suddivisione di un problema complesso in unità più piccole e gestibili. (correct)
  • La creazione di interfacce utente grafiche intuitive per facilitare l'interazione con il software.

Qual è il beneficio principale derivante dal riuso di componenti software già esistenti e verificate?

  • Limita la flessibilità del software, rendendolo meno adattabile a nuovi requisiti.
  • Riduce i tempi di sviluppo e aumenta l'affidabilità del software. (correct)
  • Aumenta la complessità del codice, rendendolo più difficile da comprendere.
  • Richiede una profonda conoscenza dei dettagli implementativi dei componenti riusati.

Cosa si intende per 'astrazione funzionale' nel contesto dello sviluppo di software?

  • L'utilizzo di funzioni di ordine superiore per manipolare altre funzioni come dati.
  • L'ottimizzazione del codice delle funzioni per migliorare le prestazioni del software.
  • La capacità di nascondere i dettagli implementativi di una funzione, concentrandosi sul suo comportamento esterno. (correct)
  • La creazione di funzioni che eseguono compiti specifici senza effetti collaterali.

In che modo l'astrazione aiuta a gestire la complessità nello sviluppo di sistemi informatici di grandi dimensioni?

<p>Permettendo di concentrarsi sugli aspetti essenziali di un problema, ignorando i dettagli irrilevanti. (A)</p> Signup and view all the answers

Considerando i principi di astrazione e information hiding, quale delle seguenti strategie architetturali li implementa al meglio?

<p>Un'architettura a microservizi dove ogni servizio espone API ben definite e nasconde i dettagli implementativi interni. (C)</p> Signup and view all the answers

Cosa succede se !q o q->numel==MAXPQ nella funzione insert?

<p>La funzione restituisce <code>0</code> per indicare che la coda è piena o non valida, impedendo l'inserimento. (A)</p> Signup and view all the answers

Qual è lo scopo principale della funzione sali?

<p>Mantenere la proprietà di heap risalendo l'albero dopo un inserimento. (B)</p> Signup and view all the answers

In un grafo orientato, cosa rappresenta l'insieme A?

<p>L'insieme delle coppie ordinate di nodi, detti archi o spigoli. (D)</p> Signup and view all the answers

Cosa rappresenta la condizione pos > 1 all'interno del ciclo while nella funzione sali?

<p>Controlla che l'elemento corrente non sia la radice dello heap. (D)</p> Signup and view all the answers

Considerando l'esempio di grafo orientato fornito, quale delle seguenti affermazioni è corretta riguardo agli archi?

<p>Esiste un arco che collega <code>u1</code> a se stesso. (C)</p> Signup and view all the answers

Quale delle seguenti affermazioni descrive correttamente un albero in informatica?

<p>Una struttura dati gerarchica che rappresenta partizioni successive di un insieme in sottoinsiemi disgiunti. (B)</p> Signup and view all the answers

Nella funzione sali, perché la variabile i è inizializzata come pos/2?

<p>Per trovare il nodo padre dell'elemento corrente nello heap. (C)</p> Signup and view all the answers

Supponendo di avere una PQueue q con q->vet = {0, 3, 7, 5, 1} e q->numel = 4, cosa succederebbe immediatamente dopo l'esecuzione di sali(q) all'interno della funzione insert con una nuova key = 9?

<p><code>q-&gt;vet</code> diventerebbe <code>{0, 9, 3, 7, 5}</code> e <code>q-&gt;numel</code> diventerebbe <code>5</code>. (C)</p> Signup and view all the answers

Qual è la caratteristica distintiva della radice in un albero?

<p>È il nodo che non ha archi entranti. (B)</p> Signup and view all the answers

Cosa rappresenta la 'foglia' in un albero?

<p>Un nodo senza archi uscenti. (A)</p> Signup and view all the answers

Come è definito il 'cammino' in un albero?

<p>Una sequenza di nodi dove ogni nodo è padre del successivo. (B)</p> Signup and view all the answers

Cosa indica il 'livello' di un nodo in un albero?

<p>La lunghezza del cammino dalla radice al nodo. (C)</p> Signup and view all the answers

Come si calcola l'altezza di un albero?

<p>Identificando il cammino più lungo dalla radice a una foglia. (D)</p> Signup and view all the answers

Quale delle seguenti affermazioni descrive correttamente un sottoalbero?

<p>Un albero formato da un nodo e tutti i suoi discendenti. (A)</p> Signup and view all the answers

In un albero binario, quale distinzione fondamentale viene fatta tra i figli di un nodo?

<p>Si distingue sempre tra figlio sinistro e figlio destro. (D)</p> Signup and view all the answers

Considerando un albero in cui ogni nodo ha un'etichetta numerica, e sapendo che l'altezza dell'albero è $h$, qual è il numero massimo di nodi che l'albero può contenere, assumendo che ogni livello sia completamente pieno?

<p>$2^{h+1} - 1$ (D)</p> Signup and view all the answers

Qual il contenuto del riferimento nell'ultimo nodo di una lista concatenata?

<p>Un valore nullo (D)</p> Signup and view all the answers

Qual uno dei principali vantaggi delle liste concatenate rispetto agli array?

<p>Maggiore flessibilit nell'inserimento e cancellazione di elementi (B)</p> Signup and view all the answers

Qual uno svantaggio principale delle liste concatenate rispetto agli array nell'accesso agli elementi?

<p>L'accesso agli elementi richiede di scorrere la lista, impiegando tempo proporzionale alla posizione dell'elemento. (A)</p> Signup and view all the answers

Come si inserisce un nuovo elemento in testa a una lista concatenata?

<p>Si crea un nuovo nodo, si collega al nodo iniziale della lista, e si aggiorna la testa della lista al nuovo nodo. (C)</p> Signup and view all the answers

Qual la complessit temporale per accedere all'i-esimo elemento in una lista concatenata?

<p>$O(i)$ (tempo proporzionale a i) (D)</p> Signup and view all the answers

In una lista concatenata, quale operazione generalmente pi efficiente rispetto agli array quando si tratta di modificare la struttura della collezione?

<p>Inserimento e cancellazione di elementi (A)</p> Signup and view all the answers

Supponendo di avere una lista concatenata semplice, non ordinata, quale sarebbe la complessit temporale nel caso peggiore per cercare un elemento specifico nella lista?

<p>$O(n)$ (D)</p> Signup and view all the answers

Se si dovesse invertire una lista concatenata semplice, qual la complessit spaziale aggiuntiva minima che si pu ottenere in un algoritmo iterativo?

<p>$O(1)$ (C)</p> Signup and view all the answers

Considera una lista concatenata in cui ogni nodo ha un puntatore al nodo successivo e un puntatore al nodo precedente (lista doppiamente concatenata). Come influisce questo sulla complessit temporale per cancellare un nodo arbitrario (non la testa o la coda) conoscendo il puntatore a quel nodo?

<p>Diminuisce a $O(1)$ perch si possono aggiornare i puntatori dei nodi adiacenti direttamente. (C)</p> Signup and view all the answers

Supponiamo di avere due liste concatenate ordinate, lista1 e lista2, di lunghezza m e n rispettivamente. Qual la complessit temporale ottimale per fondere (merge) le due liste in una nuova lista concatenata ordinata?

<p>$O(m + n)$ (D)</p> Signup and view all the answers

Quale delle seguenti affermazioni descrive correttamente la funzione newStack()?

<p>Alloca memoria per un nuovo stack e inizializza il campo <code>top</code> a 0. (A)</p> Signup and view all the answers

Cosa restituisce la funzione emptyStack(stack s)?

<p>Restituisce 1 se lo stack <code>s</code> è vuoto, altrimenti 0. (B)</p> Signup and view all the answers

Qual è il valore di ritorno della funzione push(item val, stack s) se lo stack è pieno?

<p>Restituisce 0 per indicare che l'inserimento non è avvenuto. (C)</p> Signup and view all the answers

Qual è lo scopo della funzione top(stack s)?

<p>Restituisce l'elemento in cima allo stack senza rimuoverlo. (C)</p> Signup and view all the answers

Cosa succede se si chiama pop(stack s) su uno stack vuoto?

<p>La funzione restituisce 0, segnalando che non è stato possibile estrarre alcun elemento. (C)</p> Signup and view all the answers

Considerando l'implementazione dello stack basata su array, quale operazione potrebbe causare un errore di 'stack overflow'?

<p>Eseguire ripetutamente l'operazione di <code>push</code> fino a superare <code>MAXSTACK</code> elementi. (A)</p> Signup and view all the answers

Qual è il risultato della verifica di bilanciamento delle parentesi per la stringa (a + b[c - d]) * {e / f}?

<p>bilanciate (C)</p> Signup and view all the answers

Nella funzione verifica(char *expr), cosa succede se l'espressione expr è NULL?

<p>La funzione restituisce <code>1</code>, indicando che le parentesi sono bilanciate. (D)</p> Signup and view all the answers

Data l'espressione ()[{}], quale sarà il contenuto dello stack S immediatamente prima che la funzione verifica restituisca il valore finale?

<p>Lo stack sarà vuoto. (C)</p> Signup and view all the answers

Quale modifica all'implementazione dello stack basata su array permetterebbe di evitare la limitazione di MAXSTACK (insanely difficult)?

<p>Sostituire l'array <code>vet</code> con una lista concatenata di <code>item</code>, allocando dinamicamente la memoria necessaria. (B)</p> Signup and view all the answers

Nell'implementazione dello stack basata su array dinamico, quale sequenza di eventi si verifica esattamente quando la funzione push viene chiamata con uno stack pieno (s->top == s->size) e la realloc fallisce?

<p>La funzione <code>push</code> restituisce <code>0</code>, lo stack <code>s</code> mantiene la dimensione originale e <code>s-&gt;vet</code> punta ancora alla vecchia area di memoria. (D)</p> Signup and view all the answers

Considerando l'implementazione dello stack con liste collegate, cosa accadrebbe se, all'interno della funzione pop, la riga s->top = s->top->next; venisse eseguita prima dell'assegnazione di s->top a temp?

<p>Si verificherebbe una perdita di memoria (memory leak) perché il nodo puntato da <code>s-&gt;top</code> verrebbe scollegato dalla lista senza essere deallocato. (D)</p> Signup and view all the answers

Nell'implementazione dello stack con array dinamico, se volessimo implementare una funzione clearStack(stack s) che svuota lo stack e rilascia la memoria allocata, quale sarebbe l'implementazione più corretta per evitare memory leak e dangling pointers?

<p><code>void clearStack(stack s) { free(s-&gt;vet); s-&gt;vet = NULL; s-&gt;size = 0; s-&gt;top = 0; free(s); s = NULL; }</code> (D)</p> Signup and view all the answers

Si consideri l'implementazione dello stack basata su lista concatenata. Quale delle seguenti affermazioni descrive accuratamente la complessità temporale nel caso peggiore per una sequenza di $n$ operazioni push seguite da $n$ operazioni pop?

<p>O(1) per ogni operazione, quindi O(n) per l'intera sequenza. (C)</p> Signup and view all the answers

Supponiamo di voler estendere l'implementazione dello stack basata su array dinamico per includere una funzione duplicateStack(stack s) che crea una copia profonda dello stack originale. Quale delle seguenti implementazioni garantirebbe la corretta gestione della memoria e l'indipendenza tra lo stack originale e la copia?

<p><code>stack duplicateStack(stack s) { stack newS = malloc(sizeof(struct c_stack)); newS-&gt;vet = malloc(s-&gt;size * sizeof(item)); memcpy(newS-&gt;vet, s-&gt;vet, s-&gt;top * sizeof(item)); newS-&gt;size = s-&gt;size; newS-&gt;top = s-&gt;top; return newS; }</code> (A)</p> Signup and view all the answers

In un'implementazione di posItem (versione ricorsiva), quali implicazioni deriverebbero da una gestione impropria della ricorsione terminale (tail recursion) in termini di consumo di risorse?

<p>Si verificherebbe un'allocazione eccessiva di memoria nello stack, potenzialmente portando a uno stack overflow anche con liste di dimensioni moderate, a causa della mancata ottimizzazione della ricorsione terminale. (C)</p> Signup and view all the answers

Considerando l'implementazione iterativa di posItem, quale sarebbe l'effetto di sostituire l = tailList(l) con l = newList() all'interno del ciclo while, assumendo che newList() crei una nuova lista vuota?

<p>La funzione restituirebbe -1 se il valore cercato non è il primo elemento della lista, e 0 altrimenti. (C)</p> Signup and view all the answers

Nell'implementazione di getItem, quale sarebbe l'impatto di invertire l'ordine delle condizioni nel ciclo while in while (!emptyList(l) && i < pos)?

<p>La funzione genererebbe un errore di segmentation fault qualora <code>pos</code> fosse maggiore della lunghezza della lista, poiché si tenterebbe di accedere a <code>tailList</code> su una lista vuota. (B)</p> Signup and view all the answers

Considerando la funzione reverseList, quale sarebbe la complessità computazionale nel caso in cui la funzione consList avesse una complessità temporale di $O(n)$, dove $n$ è la lunghezza della lista?

<p>$O(n^2)$ (C)</p> Signup and view all the answers

Supponendo di avere una lista lst1 contenente stringhe, e che la funzione output_item(val) stampi la stringa val. Se lst1 contiene le stringhe {"alfa", "beta", "gamma"}, in quale ordine verrebbero stampate le stringhe utilizzando la funzione outputList?

<p>&quot;alfa&quot;, &quot;beta&quot;, &quot;gamma&quot; (A)</p> Signup and view all the answers

Data l'implementazione di reverseList, se la lista originale l condividesse alcuni elementi (in memoria) con un'altra lista l2, quale sarebbe l'effetto collaterale potenziale sull'altra lista dopo l'esecuzione di reverseList(l)?

<p>Nessun effetto collaterale, poiché <code>reverseList</code> crea una nuova lista e non modifica la lista originale. (A)</p> Signup and view all the answers

Nell'implementazione ricorsiva di posItem, supponendo che la lista l sia ciclica, cosa accadrebbe all'esecuzione della funzione?

<p>La funzione entrerebbe in un ciclo infinito, causando potenzialmente uno stack overflow. (C)</p> Signup and view all the answers

Considerando una variante di outputList che utilizzi la ricorsione terminale per la visualizzazione degli elementi, quale ottimizzazione specifica del compilatore potrebbe prevenire lo stack overflow per liste estremamente lunghe?

<p>La trasformazione della ricorsione terminale in un ciclo iterativo. (B)</p> Signup and view all the answers

In una implementazione alternativa di reverseList che modifica in-place la lista originale (senza creare una nuova lista), quale sarebbe la complessità spaziale di tale algoritmo?

<p>$O(1)$. (C)</p> Signup and view all the answers

Supponiamo di voler modificare la funzione getItem per supportare l'accesso a elementi con indice negativo, dove un indice negativo -k indica il $k$-esimo elemento a partire dalla fine della lista. Come si dovrebbe modificare l'implementazione per gestire correttamente gli indici negativi mantenendo l'efficienza?

<p>Calcolare la lunghezza della lista, quindi accedere all'elemento in <code>length - abs(pos) - 1</code>. Se <code>pos &gt;= 0</code>, procedere come nell'implementazione originale. (C)</p> Signup and view all the answers

Considerando l'implementazione dell'ADT Btree fornita, quale implicazione critica scaturisce dall'indipendenza del tipo item e come influisce sulla polimorfizzazione dell'ADT stesso?

<p>L'indipendenza del tipo <code>item</code> consente di utilizzare l'ADT Btree con qualsiasi tipo di dato, a condizione che siano definite funzioni di confronto specifiche per quel tipo, estendendo così la sua utilità a strutture dati arbitrarie e personalizzate senza necessit di ricompilazione del codice Btree.c. (D)</p> Signup and view all the answers

Nell'implementazione di consBtree, la gestione della memoria tramite malloc e la successiva assegnazione di valori ai campi left e right del nuovo nodo possono potenzialmente portare a scenari problematici in sistemi con risorse limitate. Quale tra le seguenti strategie di gestione della memoria risulterebbe più efficace per mitigare tali problematiche, preservando al contempo la corretta semantica dell'ADT?

<p>Utilizzare una memory pool preallocata di dimensione fissa per i nodi dell'albero, limitando il numero massimo di nodi che possono essere creati ma garantendo tempi di allocazione costanti e prevenendo la frammentazione della memoria. (D)</p> Signup and view all the answers

Data l'implementazione dell'ADT Btree fornita, e ipotizzando di voler estendere l'interfaccia con una funzione altezzaBtree(Btree T) che calcola l'altezza dell'albero, quale delle seguenti implementazioni risulterebbe la più efficiente in termini di complessità computazionale, considerando il caso di un albero degenere (ovvero, un albero in cui ogni nodo ha al più un figlio)?

<p>Un algoritmo ricorsivo che visita ogni nodo dell'albero, calcolando l'altezza di ogni sottoalbero e restituendo il massimo tra le altezze dei sottoalberi sinistro e destro incrementato di uno, con complessità $O(n)$ nel caso degenere. (A)</p> Signup and view all the answers

Si consideri l'implementazione fornita e si ipotizzi di voler aggiungere all'ADT Btree la funzionalità di ricerca di un nodo con un determinato valore item. Quale tra le seguenti strategie di ricerca risulterebbe la meno efficiente in termini di complessità temporale nel caso medio, assumendo che l'albero non sia ordinato e che la funzione di confronto tra item abbia complessità $O(1)$?

<p>Implementare una ricerca casuale (random search) che seleziona nodi casuali nell'albero e li confronta con il valore cercato, ripetendo il processo fino a trovare il nodo o raggiungere un limite massimo di tentativi, con complessità attesa superiore a $O(n)$ nel caso medio. (D)</p> Signup and view all the answers

Nell'implementazione dell'ADT Btree basata su puntatori, quale meccanismo di protezione avanzata potrebbe essere integrato per prevenire vulnerabilità legate a dangling pointers o double free, considerando che l'ambiente di esecuzione non fornisce garbage collection automatica?

<p>Integrare un sistema di poison memory, in cui la memoria deallocata viene sovrascritta con un valore speciale (poison value) per rilevare l'accesso a dangling pointers, e implementare un meccanismo di tracciamento delle allocazioni per prevenire double free. (D)</p> Signup and view all the answers

Si consideri lo scenario in cui sia necessario serializzare un albero binario (Btree) implementato secondo l'ADT fornito, al fine di trasferirlo su una rete o memorizzarlo su disco. Quale tra i seguenti approcci di serializzazione risulterebbe più robusto e versatile per gestire alberi binari di forma arbitraria, inclusi quelli sbilanciati o degeneri, garantendo al contempo una deserializzazione corretta e efficiente?

<p>Effettuare una visita in preordine dell'albero, scrivendo su file il valore di ciascun nodo seguito dai sottoalberi sinistro e destro, rappresentando i nodi nulli con un carattere speciale, e deserializzare ricostruendo l'albero a partire dalla radice. (B)</p> Signup and view all the answers

Supponendo di voler parallelizzare l'algoritmo di visita di un albero binario (Btree) implementato secondo l'ADT fornito, con l'obiettivo di massimizzare l'utilizzo delle risorse di un'architettura multi-core, quale tra le seguenti strategie di parallelizzazione risulterebbe più efficace, considerando che la funzione getItem(node *N) potrebbe avere effetti collaterali (side effects) non trascurabili?

<p>Decomporre l'albero in sottoalberi e assegnare ad ogni core la visita di un sottoalbero indipendente, utilizzando una coda di lavoro condivisa per distribuire dinamicamente il carico e garantire un bilanciamento uniforme tra i core. (C)</p> Signup and view all the answers

In un'implementazione di una coda (queue) basata su lista concatenata, quale tra le seguenti situazioni provocherebbe una perdita di memoria (memory leak) non immediatamente evidente durante ripetute operazioni di enqueue e dequeue?

<p>Mancata deallocazione della memoria del nodo rimosso nella funzione <code>dequeue</code>, anche quando <code>q-&gt;numel</code> è decrementato correttamente. (B)</p> Signup and view all the answers

Considerando l'implementazione di una coda con array circolari, in quale scenario specifico l'operazione di enqueue fallirebbe anche se q->size < MAXQUEUE-1, e come si potrebbe correggere?

<p>Quando <code>q-&gt;tail</code> ha raggiunto <code>MAXQUEUE - 1</code> e <code>q-&gt;head</code> è diverso da zero, ma un errore nella logica impedisce il corretto riutilizzo delle posizioni iniziali dell'array. (D)</p> Signup and view all the answers

In un sistema embedded con risorse di memoria estremamente limitate, quale tra le seguenti ottimizzazioni complesse nell'implementazione di una coda basata su lista concatenata potrebbe ridurre significativamente l'overhead di memoria, pur mantenendo la funzionalità?

<p>Utilizzare un pool di allocazione personalizzato per i nodi della coda, pre-allocando un numero fisso di nodi all'avvio del sistema per evitare chiamate frequenti a <code>malloc</code> e <code>free</code>. (C)</p> Signup and view all the answers

Considerando una coda implementata con un array circolare di dimensione MAXQUEUE, quale combinazione di operazioni di enqueue e dequeue porterebbe alla situazione più critica in termini di frammentazione dello spazio nell'array, rendendo difficile il riutilizzo efficiente dello spazio anche se la coda non è piena?

<p>Una serie di <code>enqueue</code> che riempie l'array fino a <code>MAXQUEUE - 1</code>, seguita da una singola <code>dequeue</code> e poi da un tentativo di aggiungere <code>MAXQUEUE - 1</code> elementi. (C)</p> Signup and view all the answers

In un'implementazione concorrente di una coda, dove più thread eseguono operazioni di enqueue e dequeue simultaneamente, quale meccanismo di sincronizzazione avanzato sarebbe il più appropriato per garantire l'assenza di starvation e la massimizzazione della throughput, minimizzando la contesa?

<p>Una coda lock-free basata su operazioni atomiche (compare-and-swap) e memory barriers, evitando completamente l'uso di mutex e semafori. (A)</p> Signup and view all the answers

Data un'implementazione di coda basata su array con prestazioni degradanti a causa di frequenti spostamenti di elementi (quando head si avvicina alla fine dell'array), quale strategia di ristrutturazione dinamica della coda risulterebbe più efficace per mitigare questo problema senza introdurre latenza inaspettata nelle operazioni di base?

<p>Utilizzare una lista concatenata di array (chunked queue), aggiungendo un nuovo array quando il corrente si riempie e passando al successivo quando <code>head</code> raggiunge la fine del corrente. (D)</p> Signup and view all the answers

In un contesto di simulazione ad eventi discreti, dove è necessario gestire una coda di eventi ordinati per tempo di esecuzione, quale struttura dati ibrida combinerebbe i vantaggi di una coda e di un albero di ricerca bilanciato per ottimizzare sia l'inserimento (enqueue) che l'estrazione (dequeue) dell'evento con il tempo di esecuzione più imminente?

<p>Un heap binomiale, che fornisce un buon compromesso tra tempo di inserimento e tempo di estrazione del minimo. (C)</p> Signup and view all the answers

Considerando un'applicazione real-time in cui la latenza massima di un'operazione di dequeue è critica, quale implementazione di coda, combinata con quale strategia di prevenzione della frammentazione della memoria, offrirebbe la garanzia più rigorosa di rispetto dei vincoli temporali?

<p>Una coda basata su array circolare con pre-allocazione statica della memoria, evitando completamente l'allocazione dinamica durante l'esecuzione. (C)</p> Signup and view all the answers

In un sistema distribuito dove le operazioni di enqueue e dequeue avvengono su nodi differenti e la consistenza della coda deve essere garantita in presenza di guasti, quale protocollo di consenso distribuito e quale struttura dati tollerante ai guasti sarebbero più appropriati per implementare una coda distribuita ad alta affidabilità?

<p>Raft con una coda implementata utilizzando un registro distribuito consistente (es. etcd o ZooKeeper). (C)</p> Signup and view all the answers

Nell'analisi asintotica della complessità computazionale, quale combinazione di implementazione di coda e pattern di utilizzo renderebbe più evidente la differenza tra la complessità teorica e le prestazioni reali a causa di effetti di cache e branch prediction?

<p>Una coda basata su lista concatenata con allocazione dinamica casuale dei nodi, esibendo una deviazione significativa dalla complessità teorica O(1) a causa di cache misses e branch mispredictions. (C)</p> Signup and view all the answers

Considerando la specifica semantica dell'operatore removeItem(l, e), quale delle seguenti affermazioni descrive con la maggiore precisione il comportamento in caso di molteplici occorrenze dell'elemento e nella lista l?

<p>L'operatore rimuove solo la <em>prima</em> occorrenza dell'elemento <code>e</code> dalla lista <code>l</code>, lasciando intatte le eventuali occorrenze successive. (C)</p> Signup and view all the answers

Nell'implementazione dell'ADT Lista, se si volesse estendere la funzionalit base per includere un operatore concatList(list l1, list l2) che concateni due liste, creando una nuova lista contenente gli elementi di l1 seguiti da quelli di l2, quale sarebbe l'approccio pi efficiente in termini di complessit temporale, assumendo che le liste non siano ordinate e che si voglia preservare l'ordine originale degli elementi?

<p>Creare una nuova lista e copiare prima tutti gli elementi di <code>l1</code> e poi tutti gli elementi di <code>l2</code>, utilizzando <code>consList</code> per ogni elemento. Questa operazione ha complessit $O(m+n)$, dove $m$ e $n$ sono le lunghezze di <code>l1</code> e <code>l2</code> rispettivamente. (D)</p> Signup and view all the answers

Si consideri una lista concatenata implementata con le funzioni consList, tailList, getFirst ed emptyList. Si vuole implementare una funzione filterList(list l, boolean (*filter)(item)) che restituisca una nuova lista contenente solo gli elementi di l per cui la funzione filter(item) restituisce true. Quale delle seguenti implementazioni garantisce la preservazione dell'ordine originale degli elementi filtrati e minimizza l'uso di memoria aggiuntiva?

<p>Creare una nuova lista vuota e iterare sulla lista originale. Per ogni elemento che soddisfa <code>filter(item)</code>, inserirlo nella nuova lista usando <code>consList</code>. Restituire la nuova lista alla fine. (C)</p> Signup and view all the answers

Supponendo di avere accesso solo agli operatori di base dell'ADT lista ( newList, emptyList, consList, headList, tailList ), come implementeresti in modo efficiente una funzione reverseList_inplace(list l) che inverta la lista data modificandola direttamente, senza allocare nuova memoria per i nodi della lista (cio, senza creare nuovi nodi)?

<p>Usare tre puntatori: <code>prev</code>, <code>curr</code>, e <code>next</code>. Inizializzare <code>prev</code> a <code>NULL</code>, <code>curr</code> alla testa della lista. Ad ogni passo, invertire il puntatore <code>next</code> di <code>curr</code> per puntare a <code>prev</code>, quindi avanzare <code>prev</code> e <code>curr</code>. (D)</p> Signup and view all the answers

Si consideri una variante dell'ADT lista in cui ogni nodo contiene, oltre al valore dell'elemento e al puntatore al nodo successivo, un puntatore a una funzione di confronto int (*compare)(item a, item b). Come influirebbe la presenza di tale funzione sull'implementazione di un operatore sortList(list l) che ordina la lista sul posto (cio, senza allocare nuova memoria per i nodi), e quale algoritmo di ordinamento sarebbe pi appropriato in questo contesto, considerando che non si possono usare array temporanei?

<p>La funzione di confronto permetterebbe di implementare un algoritmo di ordinamento rapido (quicksort) <em>in-place</em> usando la funzione di confronto per partizionare la lista. Questo approccio avrebbe una complessit media di $O(n \log n)$, ma nel caso peggiore $O(n^2)$. (C)</p> Signup and view all the answers

In un'implementazione dell'ADT lista, si supponga di voler aggiungere una funzionalit di 'undo' che permetta di ripristinare lo stato della lista a un certo punto precedente nel tempo. Quale tra le seguenti strategie sarebbe pi appropriata per minimizzare l'impatto sulla performance delle operazioni di base (aggiunta, rimozione, accesso) e sull'utilizzo di memoria, considerando che la funzionalit di 'undo' non deve essere persistente (cio, lo stato pu essere perso alla chiusura del programma)?

<p>Mantenere uno stack di operazioni inverse (aggiunta/rimozione). L'operazione di 'undo' consiste nell'eseguire l'operazione inversa corrispondente. Questo approccio richiede meno memoria, ma aumenta la complessit delle operazioni di base. (D)</p> Signup and view all the answers

Si consideri una lista doppiamente concatenata in cui ogni nodo ha puntatori sia al nodo successivo (next) che al nodo precedente (prev). Se si volesse implementare una funzione moveNode(node* nodeToMove, list* destList) che sposta un nodo arbitrario nodeToMove da una lista ad un'altra destList, garantendo che tutte le operazioni di aggiornamento dei puntatori siano eseguite in tempo costante ($O(1)$), quale delle seguenti implementazioni minimizzerebbe il rischio di errori (come puntatori pendenti o liste corrotte) e massimizzerebbe la robustezza del codice?

<p>Come in A, ma includere controlli espliciti per gestire correttamente i casi in cui <em>nodeToMove</em> sia la testa, la coda o l'unico elemento della lista originale. Utilizzare asserzioni per verificare che i puntatori siano validi prima di ogni aggiornamento. (B)</p> Signup and view all the answers

Si consideri un'applicazione che utilizza l'ADT Lista per rappresentare una sequenza di transazioni finanziarie. A causa di requisiti normativi, necessario garantire che la lista delle transazioni sia immutabile: una volta creata, non pu essere modificata. Tuttavia, necessario supportare operazioni di filtraggio (selezionare transazioni in un certo intervallo di date) e aggregazione (calcolare la somma delle transazioni per categoria). Quale tra le seguenti combinazioni di tecniche di implementazione sarebbe pi adatta per soddisfare questi requisiti, ottimizzando al contempo le prestazioni per le operazioni di filtraggio e aggregazione?

<p>Utilizzare una lista concatenata persistente. Ogni operazione di filtraggio o aggregazione crea una nuova versione della lista, condividendo la maggior parte della struttura dati con la versione precedente. Questo garantisce l'immutabilit e pu ridurre l'uso di memoria, ma richiede una gestione complessa della memoria condivisa. (D)</p> Signup and view all the answers

Data una lista concatenata che rappresenta un polinomio, dove ogni nodo contiene il coefficiente e l'esponente di un termine (es. $3x^2$ sarebbe un nodo con coefficiente 3 ed esponente 2), e sapendo che la lista ordinata per esponente decrescente, quale algoritmo sarebbe pi efficiente per valutare il polinomio per un dato valore di $x$, minimizzando le operazioni aritmetiche e l'uso di memoria aggiuntiva?

<p>Utilizzare l'algoritmo di Horner. Questo approccio trasforma il polinomio in una forma nidificata che pu essere valutata con solo $n$ moltiplicazioni e $n$ addizioni, senza richiedere memoria aggiuntiva. (D)</p> Signup and view all the answers

Considerando l'implementazione iterativa di posItem, cosa accadrebbe se la condizione !emptyList(l) && !found venisse modificata in !found && !emptyList(l)?

<p>La funzione potrebbe comportare un errore di accesso alla memoria se <code>l</code> fosse una lista vuota, poich si tenterebbe di dereferenziare un puntatore nullo. (D)</p> Signup and view all the answers

Nell'implementazione ricorsiva di posItem, cosa succederebbe se si omettesse il controllo if emptyList(l) return -1;?

<p>La funzione causerebbe un errore di segmentation fault quando raggiunge la fine della lista. (D)</p> Signup and view all the answers

Nella funzione getItem, se la condizione pos < 0 fosse omessa, quale sarebbe il comportamento della funzione quando pos un numero negativo?

<p>La funzione potrebbe accedere a zone di memoria non valide, causando comportamenti indefiniti. (B)</p> Signup and view all the answers

Supponiamo di voler modificare getItem per gestire posizioni superiori alla lunghezza della lista, restituendo l'ultimo elemento anzich NULLITEM. Come si dovrebbe modificare la funzione?

<p>Aggiungere un controllo dopo il ciclo <code>while</code> per restituire l'ultimo elemento se <code>emptyList(l)</code> vera. (A)</p> Signup and view all the answers

Nella funzione reverseList, cosa succederebbe se la riga l = tailList(l) venisse omessa all'interno del ciclo while?

<p>La funzione entrerebbe in un ciclo infinito. (D)</p> Signup and view all the answers

Supponendo che la funzione consList abbia una complessit temporale di $O(1)$, qual la complessit temporale della funzione reverseList?

<p>$O(n)$ (A)</p> Signup and view all the answers

Nella funzione outputList, cosa accadrebbe se la riga i++; venisse spostata prima della chiamata a output_item(val)?

<p>L'indice degli elementi visualizzati sarebbe sfasato di uno, iniziando da 1 anzich da 0. (D)</p> Signup and view all the answers

Si consideri una variante di outputList in cui si desidera interrompere la visualizzazione dopo un certo numero di elementi, ad esempio 5. Quale modifica sarebbe necessaria per implementare questa funzionalit?

<p>Aggiungere una condizione <code>if (i &gt; 5) return;</code> all'interno del ciclo <code>while</code>. (C)</p> Signup and view all the answers

Qual è la differenza fondamentale tra un file header (.h) e un file di implementazione (.c) in un modulo C?

<p>Il file .h contiene le dichiarazioni delle funzioni e delle variabili, mentre il file .c contiene le definizioni delle funzioni e le dichiarazioni statiche. (D)</p> Signup and view all the answers

Quale dei seguenti è un vantaggio chiave dell'utilizzo di moduli in C per l'implementazione di astrazioni funzionali?

<p>Facilita l'information hiding, riducendo gli effetti collaterali e nascondendo le funzioni di servizio. (B)</p> Signup and view all the answers

Dove dovrebbero essere inseriti i commenti relativi alla specifica di una funzione in un modulo C?

<p>Nel file .h, prima del prototipo della funzione. (A)</p> Signup and view all the answers

Considerando un modulo vettore con funzioni come ordina_array e ricerca_array, e un programma principale ordina_array.c che utilizza questo modulo, quale direttiva #include è necessaria in ordina_array.c per utilizzare le funzioni del modulo vettore?

<p><code>#include &quot;vettore.h&quot;</code> (B)</p> Signup and view all the answers

Nell'esempio fornito, la funzione minimo_i è dichiarata nel file vettore.c, ma non nel file vettore.h. Cosa implica questo?

<p>La funzione <code>minimo_i</code> è una funzione di servizio interna al modulo <code>vettore</code> e non è accessibile dall'esterno. (A)</p> Signup and view all the answers

Se il modulo utile contiene una funzione scambia e il modulo vettore necessita di utilizzare scambia, come dovrebbe essere gestita l'inclusione dei file header?

<p>Il file <code>vettore.c</code> dovrebbe includere <code>utile.h</code>. (C)</p> Signup and view all the answers

Quale delle seguenti affermazioni descrive meglio lo scopo del file header di un modulo C dal punto di vista del "cliente" del modulo?

<p>Fornisce l'interfaccia pubblica del modulo, consentendo al cliente di conoscere le funzioni disponibili e come utilizzarle. (D)</p> Signup and view all the answers

Un modulo client include il file header di un altro modulo. Se quest'ultimo modulo viene aggiornato con nuove funzioni o modifiche implementative, quale tra le seguenti azioni non è generalmente necessaria nel modulo client, assumendo che l'interfaccia pubblica (dichiarazioni nell'header file) rimanga compatibile?

<p>Modificare l'header file del modulo client. (B)</p> Signup and view all the answers

Considerando l'implementazione dello stack con array, quale svantaggio principale emerge quando si raggiunge la capacità massima MAXSTACK?

<p>Non è più possibile aggiungere elementi allo stack, limitandone l'uso. (A)</p> Signup and view all the answers

Nella specifica semantica dell'ADT Stack, cosa rappresenta l'elemento 'nil'?

<p>Uno stack vuoto, privo di elementi. (D)</p> Signup and view all the answers

Secondo la specifica semantica dell'operatore push(e, s) → s', cosa implica la condizione s = <a1, a2, ..., an> e s' = <e, a1, a2, ..., an>?

<p>L'elemento 'e' viene inserito in cima allo stack 's', creando un nuovo stack 's'' con 'e' come nuovo elemento in cima. (D)</p> Signup and view all the answers

Supponendo di avere uno stack s = <5, 8, 2>, quale sarà il risultato dell'operazione top(s)?

<p>Restituirà l'elemento <code>5</code>. (A)</p> Signup and view all the answers

Nell'implementazione di uno stack con array, cosa indica il valore della variabile top?

<p>La posizione successiva a quella dell’elemento in cima allo stack, equivalente al numero di elementi presenti. (D)</p> Signup and view all the answers

Considerando uno stack implementato con un array di dimensione MAXSTACK, in quale momento preciso l'operazione push fallisce?

<p>Quando <code>top</code> è uguale a <code>MAXSTACK</code>. (B)</p> Signup and view all the answers

Quale tra le seguenti affermazioni descrive meglio l'utilità dell'header file stack.h in un'implementazione di stack in C?

<p>Fornisce i prototipi delle funzioni per manipolare lo stack, nascondendo i dettagli implementativi. (C)</p> Signup and view all the answers

Se si volesse modificare l'implementazione dello stack per supportare tipi di dati diversi da item, pur mantenendo l'indipendenza dal tipo, quale approccio sarebbe più appropriato?

<p>Utilizzare un array di tipo <code>void*</code> per memorizzare gli elementi e fare casting quando necessario. (B)</p> Signup and view all the answers

Quale tra le seguenti descrizioni rappresenta meglio il concetto di 'astrazione sui dati'?

<p>Un paradigma che permette di nascondere i dettagli implementativi di un dato, esponendo solo un insieme di operazioni ben definite, utilizzabili a prescindere dall'implementazione. (C)</p> Signup and view all the answers

In che modo il concetto di 'information hiding' contribuisce alla realizzazione di alti livelli di astrazione?

<p>Definendo vincoli di inaccessibilità ai dettagli implementativi, permettendo ai clienti di interagire con le risorse e i servizi offerti senza dipendere da tali dettagli. (B)</p> Signup and view all the answers

Qual è la differenza fondamentale tra 'astrazione' e 'information hiding' nella progettazione di un sistema software?

<p>L'astrazione si concentra sulla definizione delle entità funzionali, mentre l'information hiding definisce ed impone vincoli di inaccessibilità ai dettagli implementativi. (B)</p> Signup and view all the answers

Quale delle seguenti affermazioni descrive meglio la funzione di un'interfaccia di un modulo?

<p>Definisce le risorse e i servizi messi a disposizione dei clienti, nascondendo i dettagli implementativi. (D)</p> Signup and view all the answers

In un modulo software, qual è lo scopo principale della sezione implementativa (body)?

<p>Implementare le risorse e i servizi esportanti, mantenendo nascosti i dettagli di realizzazione. (C)</p> Signup and view all the answers

Come si realizza tipicamente il concetto di modulo nel linguaggio di programmazione C, considerando che C non ha un costrutto esplicito per i moduli?

<p>Sfruttando un'opportuna combinazione di header files (.h) per l'interfaccia e file sorgente (.c) per l'implementazione, unitamente alle regole di visibilità. (B)</p> Signup and view all the answers

Qual è la funzione principale di un header file (.h) in C quando viene utilizzato per definire l'interfaccia di un modulo?

<p>Dichiarare le funzioni, le strutture dati e le costanti che il modulo mette a disposizione di altri moduli, senza rivelarne l'implementazione. (B)</p> Signup and view all the answers

Per accedere alle risorse (funzioni, variabili, tipi di dato) esportate da un modulo in C, cosa è necessario fare?

<p>Includere l'header file del modulo utilizzando la direttiva <code>#include</code> nel file sorgente che utilizza le risorse del modulo. (B)</p> Signup and view all the answers

Nel contesto del codice fornito, quale delle seguenti affermazioni descrive meglio lo scopo della funzione input_punti?

<p>Richiede all'utente di inserire le coordinate per un numero specificato di punti e li memorizza in un array. (D)</p> Signup and view all the answers

Considerando la funzione coppie_vicine, cosa accadrebbe se il ciclo for interno fosse modificato in for(j=0; j < n; j++)?

<p>La funzione calcolerebbe la distanza di ogni punto da se stesso, oltre che dagli altri. (C)</p> Signup and view all the answers

Quale delle seguenti modifiche al codice punto.h comprometterebbe la compilazione del file vicini.c senza alterare l'interfaccia pubblica (nomi e parametri delle funzioni)?

<p>Omettere la definizione <code>typedef struct pto *punto;</code>. (A)</p> Signup and view all the answers

Se la funzione creaPunto non allocasse memoria dinamicamente utilizzando malloc, quale problema si verificherebbe nel programma principale?

<p>I punti verrebbero sovrascritti, poiché tutti punterebbero alla stessa locazione di memoria. (A)</p> Signup and view all the answers

Supponendo che la funzione distanza venisse modificata per calcolare il quadrato della distanza invece della distanza effettiva (rimuovendo la sqrt), come influenzerebbe il risultato finale del programma?

<p>Il programma troverebbe un numero diverso di coppie vicine, dato che il confronto cambierebbe. (A)</p> Signup and view all the answers

Nell'esercizio proposto sull'ADT Vettore, se si utilizzasse un array statico (anziché allocazione dinamica) per implementare il vettore, quale sarebbe la principale limitazione?

<p>La dimensione del vettore dovrebbe essere nota a tempo di compilazione. (B)</p> Signup and view all the answers

Quale delle seguenti modifiche minime al codice renderebbe la funzione coppie_vicine più efficiente in termini di prestazioni, specialmente per un grande numero di punti?

<p>Memorizzare la distanza calcolata in una variabile temporanea per evitare ricalcoli. (D)</p> Signup and view all the answers

Se si volesse estendere l'ADT punto con una funzione traslaPunto(punto p, float dx, float dy) che trasla il punto di dx e dy, quale sarebbe l'implementazione corretta mantenendo l'incapsulamento?

<p><code>p-&gt;x += dx; p-&gt;y += dy; return p;</code> (A)</p> Signup and view all the answers

In un programma che utilizza l'ADT Vettore, se dopo aver allocato dinamicamente un vettore con malloc, non si deallocasse la memoria con free quando il vettore non è più necessario, quale problema si presenterebbe?

<p>Si verificherebbe una perdita di memoria (memory leak), riducendo la memoria disponibile per altre operazioni. (B)</p> Signup and view all the answers

Considerando l'importanza dell'astrazione, quale beneficio non è direttamente ottenuto dall'uso di un ADT (Abstract Data Type) ben progettato, come l'ADT punto?

<p>Aumento automatico della velocità di esecuzione del programma. (A)</p> Signup and view all the answers

Quale delle seguenti affermazioni descrive meglio il comportamento della funzione top(stack s) quando lo stack s è vuoto?

<p>Restituisce <code>NULLITEM</code> definito nel file item.h. (B)</p> Signup and view all the answers

Considerando l'implementazione dello stack basata su array, cosa succede se si tenta di inserire un elemento in uno stack già pieno?

<p>La funzione <code>push</code> restituisce 0 per indicare fallimento. (A)</p> Signup and view all the answers

Nella funzione verifica(char *expr), quale condizione implica che l'espressione contiene parentesi sbilanciate?

<p>Si incontra una parentesi chiusa quando lo stack <code>S</code> è vuoto. (A)</p> Signup and view all the answers

Cosa rappresenta la funzione corrisp(char a, char b)?

<p>Verifica se <code>b</code> è la parentesi chiusa corrispondente alla parentesi aperta <code>a</code>. (D)</p> Signup and view all the answers

Se la funzione verifica riceve in input la stringa (a+b[c-d, cosa accadrà?

<p>Restituirà 'parentesi sbilanciate' perché lo stack non è vuoto alla fine. (D)</p> Signup and view all the answers

Quale è il ruolo della funzione newStack()?

<p>Creare un nuovo stack vuoto e allocare la memoria necessaria. (B)</p> Signup and view all the answers

Cosa si intende quando si dice che l'espressione (4 + a) * {[1 – (2/x)] * (8 – a)} è ben bilanciata?

<p>Che ogni parentesi aperta ha una corrispondente parentesi chiusa dello stesso tipo, e sono correttamente annidate. (B)</p> Signup and view all the answers

Nell'implementazione fornita, qual è la complessità temporale della funzione push?

<p>$O(1)$ (costante). (B)</p> Signup and view all the answers

Nell'implementazione dell'ADT stack con array, quale modifica sarebbe necessaria per gestire dinamicamente la dimensione massima dello stack ( MAXSTACK )?

<p>Utilizzare la funzione <code>realloc()</code> per ridimensionare l'array quando è pieno. (C)</p> Signup and view all the answers

Perché nella progettazione dell'algoritmo di verifica del bilanciamento delle parentesi si suggerisce di 'estrarre dall’espressione solo le parentesi, cancellando tutto il resto'?

<p>Tutte le risposte precedenti sono corrette. (C)</p> Signup and view all the answers

Cosa cambierebbe nell'algoritmo di verifica del bilanciamento se si volesse considerare una priorità tra i tipi di parentesi (es. le parentesi tonde devono essere chiuse prima delle quadre)?

<p>Si dovrebbe introdurre un meccanismo per tenere traccia dell'ordine di apertura delle parentesi e verificarlo in chiusura. (A)</p> Signup and view all the answers

Se l'espressione da analizzare contenesse caratteri diversi dalle parentesi (es. lettere, numeri, operatori), quale delle seguenti scelte sarebbe la più efficiente in termini di prestazioni?

<p>Modificare la funzione <code>verifica</code> per filtrare i caratteri non rilevanti durante la scansione. (D)</p> Signup and view all the answers

Cosa si dovrebbe fare per implementare uno stack che non abbia una dimensione massima fissa?

<p>Utilizzare una lista concatenata per memorizzare gli elementi. (B)</p> Signup and view all the answers

Quale tra queste affermazioni è vera riguardo all'uso di malloc nella funzione newStack()?

<p>Serve ad allocare dinamicamente la memoria necessaria per la struttura dello stack. (B)</p> Signup and view all the answers

Supponendo di voler modificare l'implementazione dello stack per supportare un numero illimitato di elementi, quale sarebbe la principale implicazione in termini di gestione della memoria?

<p>Sarebbe necessario allocare e deallocare dinamicamente la memoria per ogni elemento inserito o rimosso dallo stack. (B)</p> Signup and view all the answers

In un ADT Lista, quale tra le seguenti affermazioni descrive meglio la relazione tra l'operatore tailList(l) e la lista originale l dopo l'esecuzione dell'operazione, considerando che l non sia vuota?

<p><code>tailList(l)</code> restituisce una nuova lista concatenata, <code>l'</code>, composta da tutti gli elementi di <code>l</code> eccetto il primo, senza modificare la lista originale <code>l</code>; le due liste sono entità distinte in memoria. (B)</p> Signup and view all the answers

Quale delle seguenti affermazioni descrive completamente le implicazioni dell'uso di un tipo item generico nella specifica dell'ADT Lista?

<p>L'ADT Lista è indipendente dal tipo degli elementi che contiene, permettendo di memorizzare qualsiasi tipo di dato senza modifiche all'ADT stesso, a patto che siano gestiti correttamente i puntatori. (C)</p> Signup and view all the answers

Si consideri una lista concatenata l implementata secondo l'ADT fornito, contenente $n$ elementi. Qual è la complessità computazionale minima nel caso peggiore per inserire un nuovo elemento in una posizione specifica (diversa dall'inizio) della lista, se non si ha un riferimento diretto al nodo precedente?

<p>$O(n)$, poiché è necessario scorrere la lista dal primo elemento fino alla posizione desiderata. (B)</p> Signup and view all the answers

Considerando l'implementazione di una coda con liste collegate, quale tra le seguenti operazioni richiederebbe una gestione specialmente attenta per evitare race conditions in un ambiente multithreaded?

<p>L'esecuzione concorrente di <code>enqueue</code> e <code>dequeue</code> quando la coda è quasi vuota (pochi elementi). (C)</p> Signup and view all the answers

Nell'implementazione di una lista concatenata, quale tra le seguenti strategie sarebbe più efficace per minimizzare il rischio di memory leak e dangling pointer durante l'eliminazione di un nodo, specialmente in un ambiente senza garbage collection automatica?

<p>Prima di deallocare un nodo, assicurarsi che tutti i puntatori ad esso siano aggiornati o impostati a <code>NULL</code>, e considerare l'uso di strumenti di analisi statica del codice per identificare potenziali memory leaks. (B)</p> Signup and view all the answers

Supponendo di voler implementare una funzione concatList(list l1, list l2) che concateni due liste immutabili l1 e l2, creando una nuova lista l3 contenente gli elementi di l1 seguiti da quelli di l2, quale tra le seguenti implementazioni sarebbe più efficiente in termini di complessità temporale e spaziale, garantendo al contempo che le liste originali l1 e l2 rimangano inalterate (cioè, preservando l'immutabilità)?

<p>Creare una nuova lista <code>l3</code> e copiare prima tutti gli elementi di <code>l1</code> e poi tutti gli elementi di <code>l2</code> in <code>l3</code>, utilizzando <code>consList</code> per ogni inserimento. Questo approccio ha complessità $O(m+n)$ dove $m$ e $n$ sono le lunghezze di <code>l1</code> e <code>l2</code> rispettivamente. (D)</p> Signup and view all the answers

Data un'implementazione di coda tramite array circolari, quale sequenza di operazioni porterebbe più rapidamente a una situazione in cui la coda risulta piena, ma in realtà presenta ancora spazio disponibile a causa della natura circolare dell'array?

<p>L'esecuzione di <code>enqueue</code> e <code>dequeue</code> in modo tale che l'indice <code>head</code> raggiunga <code>MAXQUEUE - 1</code> e l'indice <code>tail</code> sia a <code>0</code>. (D)</p> Signup and view all the answers

In un'implementazione di coda basata su array, quale condizione aggiuntiva deve essere verificata per determinare se la coda è vuota, oltre al semplice confronto tra gli indici head e tail?

<p>È necessario che sia <code>head == tail</code> e che la coda sia stata precedentemente inizializzata, verificando che <code>head</code> e <code>tail</code> abbiano valori validi (ad esempio, 0). (C)</p> Signup and view all the answers

Nell'implementazione dell'ADT Queue con liste concatenate, come si adatterebbe la gestione della memoria se si volesse supportare una politica di "coda persistente", in cui ogni operazione di enqueue o dequeue non modifica la coda originale, ma ne crea una nuova versione?

<p>Si potrebbe utilizzare una tecnica di &quot;copy-on-write&quot; per condividere parti della lista tra diverse versioni della coda, fino a quando non è necessaria una modifica. (A)</p> Signup and view all the answers

In un sistema real-time in cui si utilizza una coda per gestire task con priorità diverse e stringenti vincoli temporali sull'esecuzione, quale tra le seguenti modifiche all'implementazione standard dell'ADT Queue non sarebbe appropriata?

<p>Aggiungere un meccanismo di locking <em>fine-grained</em> (ad esempio, uno per ogni nodo della lista) per permettere a più thread di accedere contemporaneamente alla coda. (C)</p> Signup and view all the answers

Quale delle seguenti affermazioni descrive correttamente la differenza fondamentale tra la visita in preordine e la visita in postordine di un albero binario?

<p>La visita in preordine visita la radice prima di visitare i sottoalberi, mentre la visita in postordine visita la radice dopo aver visitato entrambi i sottoalberi. (C)</p> Signup and view all the answers

Nella visita simmetrica (inorder) di un albero binario, quale tra le seguenti è la sequenza corretta di operazioni?

<p>Visita del sottoalbero sinistro, analisi della radice, visita del sottoalbero destro. (B)</p> Signup and view all the answers

Considerando l'implementazione ricorsiva della funzione inputBtree(), quale condizione determina il caso base della ricorsione, arrestando la costruzione di un ramo dell'albero?

<p>Quando viene rilevato che l'albero è vuoto. (D)</p> Signup and view all the answers

Durante la costruzione ricorsiva di un albero binario tramite la funzione inputBtree(), in quale ordine preciso vengono richieste le informazioni all'utente?

<p>È albero vuoto?, radice, sottoalbero sinistro, sottoalbero destro. (B)</p> Signup and view all the answers

Volendo implementare una funzione iterativa per la visita in preordine di un albero binario, quale struttura dati si rivela fondamentale per mantenere traccia dei nodi da visitare?

<p>Uno stack, per gestire l'ordine di ritorno ai nodi superiori. (C)</p> Signup and view all the answers

Considerando che le visite in preordine, inordine e postordine possono essere implementate sia ricorsivamente che iterativamente, quale delle seguenti affermazioni descrive accuratamente una differenza chiave tra i due approcci in termini di gestione della memoria?

<p>L'implementazione ricorsiva utilizza implicitamente lo stack di sistema per gestire le chiamate, mentre l'implementazione iterativa richiede una gestione esplicita dello stack tramite una struttura dati. (D)</p> Signup and view all the answers

Nel contesto dell'ADT Lista, quale delle seguenti affermazioni cattura l'essenza del concetto di sequenza?

<p>L'ordine degli elementi è significativo e definisce la lista. (B)</p> Signup and view all the answers

Quale tra le seguenti è una limitazione intrinseca del tipo astratto di dato (ADT) Lista, rispetto ad altre strutture dati come gli alberi o i grafi?

<p>L'assenza di una struttura gerarchica o di relazioni complesse tra gli elementi. (C)</p> Signup and view all the answers

In una lista concatenata, quale tra le seguenti operazioni ha la complessità temporale più alta nel caso peggiore?

<p>Accedere all'ennesimo elemento della lista. (A)</p> Signup and view all the answers

Si consideri l'inserimento di un nuovo nodo in testa a una lista concatenata. Quale sequenza di operazioni è strettamente necessaria per garantire che la lista rimanga coerente e accessibile?

<p>Creare il nuovo nodo, impostare il campo <code>next</code> del nuovo nodo a puntare all'attuale testa della lista, e poi aggiornare il puntatore alla testa della lista per puntare al nuovo nodo. (C)</p> Signup and view all the answers

In una lista concatenata, quale delle seguenti affermazioni descrive correttamente la relazione tra la flessibilità della lista e l'accesso agli elementi?

<p>La maggiore flessibilità nell'inserimento e cancellazione di elementi comporta la perdita dell'accesso diretto agli elementi, richiedendo la scansione sequenziale. (C)</p> Signup and view all the answers

Se si dovesse progettare una struttura dati che combini la flessibilità delle liste concatenate con la capacità di accesso rapido agli elementi tipica degli array, quale delle seguenti strutture dati ibride sarebbe la più appropriata, considerando l'overhead di spazio e la complessità di implementazione?

<p>Una lista concatenata di array, dove ogni nodo della lista contiene un array di elementi. (C)</p> Signup and view all the answers

In una lista concatenata che rappresenta una coda, dove gli elementi vengono aggiunti alla fine e rimossi dall'inizio, quale sarebbe l'impatto sull'efficienza dell'operazione di dequeue se la lista fosse implementata senza un puntatore alla coda (ultimo elemento)?

<p>L'operazione di <code>dequeue</code> diventerebbe più costosa, richiedendo la scansione dell'intera lista per trovare il nuovo ultimo elemento. (D)</p> Signup and view all the answers

Quale delle seguenti affermazioni descrive correttamente la distinzione fondamentale tra la specifica sintattica e la specifica semantica di un tipo di dato astratto?

<p>La specifica sintattica stabilisce i <em>tipi di dati</em> coinvolti e le firme degli operatori, mentre la specifica semantica definisce il <em>significato</em> e il comportamento degli operatori tramite precondizioni e postcondizioni. (B)</p> Signup and view all the answers

Considerando il tipo di dato astratto 'libro', quale delle seguenti asserzioni rappresenta correttamente una possibile estensione della specifica semantica dell'operatore creaLibro con una precondizione?

<p><code>Pre: an &gt; 0 &amp;&amp; an &lt; currentYear()</code>; <code>Post: lb = (aut, tit, ed, an)</code> (D)</p> Signup and view all the answers

Nell'esempio del tipo di dato astratto 'libro', le postcondizioni degli operatori autore, titolo, editore e anno sono tutte nella forma Post: lb = (aut, tit, ed, an). Quale delle seguenti interpretazioni descrive al meglio il significato di queste postcondizioni?

<p>Queste postcondizioni assicurano che gli operatori siano <em>puri</em>, ovvero non producano effetti collaterali e non modifichino l'oggetto <code>libro</code>. (D)</p> Signup and view all the answers

Supponiamo di voler aggiungere un operatore modificaAnno(libro, intero) al tipo di dato astratto 'libro'. Quale delle seguenti coppie precondizione/postcondizione descrive correttamente il comportamento di un operatore che modifica l'anno di pubblicazione solo se l'anno fornito è valido (positivo)?

<p><code>Pre: true</code>; <code>Post: lb' = (aut, tit, ed, an') if an &gt; 0 else lb' = lb</code> (B)</p> Signup and view all the answers

Nel contesto della realizzazione di un tipo di dato astratto, quale dei seguenti aspetti è primariamente gestito dai meccanismi di programmazione modulare?

<p>L'organizzazione del codice in unità separate, l'interfaccia con il mondo esterno e l'occultamento dei dettagli implementativi. (C)</p> Signup and view all the answers

Considerando l'astrazione del tipo di dato 'libro', se volessimo aggiungere un operatore confrontaLibri(libro lb1, libro lb2) che restituisce un valore booleano indicando se due libri sono uguali (stesso autore, titolo, editore e anno), quale sarebbe la specifica semantica più completa per questo operatore?

<p><code>Post: result = (lb1.autore == lb2.autore &amp;&amp; lb1.titolo == lb2.titolo &amp;&amp; lb1.editore == lb2.editore &amp;&amp; lb1.anno == lb2.anno)</code> (C)</p> Signup and view all the answers

Supponiamo di avere una realizzazione del tipo di dato astratto 'libro' in cui l'anno è rappresentato come una stringa anziché un intero. Quale impatto avrebbe questo cambiamento principalmente sulla specifica del tipo di dato?

<p>Richiederebbe una modifica sia alla specifica sintattica che alla specifica semantica. (B)</p> Signup and view all the answers

In termini di information hiding nella realizzazione del tipo di dato astratto 'libro', quale delle seguenti scelte progettuali supporta meglio questo principio?

<p>Dichiarare la struttura interna del libro come <code>typedef struct libro {...}</code> nel file di implementazione (.c) e fornire solo le dichiarazioni delle funzioni (creaLibro, autore, ecc.) nel file header (.h). (A)</p> Signup and view all the answers

Se la precondizione di un operatore in un tipo di dato astratto non è soddisfatta al momento della chiamata, quale fra le seguenti è la conseguenza più appropriata in termini di progettazione e robustezza del software?

<p>L'operatore dovrebbe segnalare una condizione di errore (ad esempio, tramite un valore di ritorno speciale o un'eccezione) e interrompere l'esecuzione. (B)</p> Signup and view all the answers

Nell'ambito della manutenzione e dell'evoluzione di un tipo di dato astratto, quale tra le seguenti modifiche sarebbe meno problematica per i client che utilizzano il tipo di dato, assumendo che le specifiche sintattiche e semantiche degli operatori rimangano invariate?

<p>La modifica della struttura dati interna utilizzata per rappresentare il tipo di dato. (D)</p> Signup and view all the answers

Nell'implementazione dinamica dello stack (senza dimensione massima fissa), cosa accadrebbe se la funzione realloc in push restituisse NULL?

<p>La funzione <code>push</code> restituirebbe <code>0</code>, segnalando il fallimento dell'operazione, e lo stack rimarrebbe nello stato precedente. (D)</p> Signup and view all the answers

Nell'implementazione dello stack basata su array dinamico, perché è necessario utilizzare realloc anziché malloc per aumentare la dimensione dell'array?

<p><code>realloc</code> permette di preservare gli elementi già presenti nello stack, mentre <code>malloc</code> creerebbe un nuovo array vuoto. (A)</p> Signup and view all the answers

In una implementazione di stack basata su array dinamico, se si verificasse un errore durante la realloc nella funzione push, quale sarebbe la migliore strategia per la gestione della memoria al fine di prevenire memory leaks?

<p>Liberare la memoria puntata da <code>tmp</code> (la variabile temporanea che riceve il risultato di <code>realloc</code>) prima di restituire <code>0</code>, ma solo se <code>tmp</code> è diverso da <code>s-&gt;vet</code>. (A)</p> Signup and view all the answers

Nell'implementazione dello stack con lista concatenata, quale operazione deve essere eseguita prima di modificare s->top nella funzione pop per evitare memory leaks?

<p>Salvare il valore di <code>s-&gt;top</code> in una variabile temporanea e liberare la memoria puntata da quella variabile. (B)</p> Signup and view all the answers

In una implementazione di stack basata su lista concatenata, quale sarebbe l'effetto più probabile di non decrementare il campo numel nella funzione pop dopo aver rimosso un elemento?

<p>La funzione <code>emptyStack</code> potrebbe restituire risultati errati, indicando uno stack non vuoto anche quando lo è. (A)</p> Signup and view all the answers

Considerando l'implementazione dello stack basata su liste collegate, cosa accadrebbe se nella funzione push la riga nuovo->next = s->top; venisse omessa?

<p>Lo stack diventerebbe inutilizzabile, poiché <code>s-&gt;top</code> punterebbe a un nodo isolato. (C)</p> Signup and view all the answers

Nel contesto dell'implementazione dello stack con lista concatenata, quale è il principale svantaggio in termini di overhead di memoria rispetto all'implementazione con array dinamico?

<p>Ogni elemento nello stack con lista concatenata richiede memoria aggiuntiva per il puntatore <code>next</code>, mentre nell'array dinamico gli elementi sono contigui. (A)</p> Signup and view all the answers

Se si volesse implementare una funzione clearStack(stack s) per l'implementazione dello stack basata su lista concatenata, quale sarebbe l'implementazione più corretta per evitare memory leaks?

<p>Iterare attraverso ogni elemento dello stack, liberando la memoria di ogni nodo e poi assegnare <code>NULL</code> a <code>s-&gt;top</code> e impostare <code>s-&gt;numel</code> a 0. (D)</p> Signup and view all the answers

Nell'implementazione dello stack basata sul modulo lista, cosa cambierebbe fondamentalmente nel comportamento dello stack se si decidesse di utilizzare una lista coda (con puntatori sia alla testa che alla coda) invece di una lista semplice?

<p>Non ci sarebbero cambiamenti funzionali, dato che lo stack utilizza solo l'operazione di inserimento e rimozione in testa. (A)</p> Signup and view all the answers

Considerando l'implementazione dello stack basata sull'uso del modulo lista fornito, e supponendo di voler aggiungere una funzione sizeStack(stack s) che restituisca il numero di elementi nello stack, quale delle seguenti affermazioni è più accurata riguardo alla sua implementazione e complessità?

<p>La funzione <code>sizeStack(stack s)</code> può essere implementata iterando attraverso la lista e contando gli elementi, con complessità $O(n)$, dove $n$ è il numero di elementi nello stack. (D)</p> Signup and view all the answers

Flashcards

GRAFO

Struttura dati che include LISTE e ALBERI.

ALBERO (struttura dati)

Struttura informativa per rappresentare partizioni, gerarchie e processi decisionali.

Radice (albero)

Un nodo senza archi entranti in un albero.

Foglia (albero)

Nodo senza archi uscenti.

Signup and view all the flashcards

Cammino (in un albero)

Sequenza di nodi dove ogni nodo è padre del successivo.

Signup and view all the flashcards

Grado di un nodo

Numero di figli di un nodo.

Signup and view all the flashcards

Livello di un nodo

Lunghezza del cammino dalla radice a un nodo.

Signup and view all the flashcards

Cos'è 'sali' in un heap?

Un operazione per mantenere le proprietà di un heap dopo un inserimento, spostando un nodo verso l'alto finché non è nella posizione corretta.

Signup and view all the flashcards

Cosa fa la funzione insert?

Inserisce una nuova chiave in coda e ripristina le proprietà dell'heap.

Signup and view all the flashcards

Altezza dell'albero

Lunghezza del cammino più lungo dalla radice a una foglia.

Signup and view all the flashcards

Albero Binario

Albero dove ogni nodo ha al massimo due figli (sinistro e destro).

Signup and view all the flashcards

Cos'è un grafo orientato?

Un grafo orientato è una coppia di insiemi: un insieme finito di nodi (N) e un insieme finito di archi (A), dove A è un sottoinsieme di coppie ordinate di nodi.

Signup and view all the flashcards

Cosa sono i nodi (N)?

L'insieme finito non vuoto di punti in un grafo.

Signup and view all the flashcards

Cosa sono gli archi (A)?

L'insieme di coppie ordinate di nodi che rappresentano le connessioni tra i nodi in un grafo.

Signup and view all the flashcards

Cos'è un Grafo?

Una rappresentazione visiva di connessioni tra entità.

Signup and view all the flashcards

Cos'è 'scendi' in un heap?

Un operazione per mantenere le proprietà di un heap dopo una rimozione o modifica, spostando un nodo verso il basso finché non è nella posizione corretta.

Signup and view all the flashcards

Progettazione

Il processo di ideazione della soluzione informatica a un problema, dall'architettura ai dati.

Signup and view all the flashcards

Modularizzazione

Dividere un programma in unità (moduli) per gestire la complessità.

Signup and view all the flashcards

Modulo

Un'unità di programma che offre risorse e servizi computazionali (dati, funzioni).

Signup and view all the flashcards

Astrazione

Evidenziare le caratteristiche principali di un problema, ignorando i dettagli secondari.

Signup and view all the flashcards

Astrazione funzionale

Concentrarsi su cosa fa un sottoprogramma, senza preoccuparsi di come lo fa.

Signup and view all the flashcards

Riferimento dell'ultimo nodo

In una lista concatenata, l'ultimo nodo punta a...

Signup and view all the flashcards

Lista concatenata

Una struttura dati flessibile che permette inserimenti e cancellazioni efficienti.

Signup and view all the flashcards

Accesso sequenziale

A differenza degli array, l'accesso agli elementi richiede di scorrere la lista.

Signup and view all the flashcards

Inserimento in testa (lista)

Operazione per aggiungere un nuovo elemento all'inizio della lista. È una metodologia semplice ed efficace.

Signup and view all the flashcards

Creazione nuovo nodo L

Il primo passo è creare uno spazio per contenere il dato da inserire.

Signup and view all the flashcards

Collegamento al record iniziale

Il nuovo nodo deve essere collegato al resto della lista esistente.

Signup and view all the flashcards

Tempo di accesso array

Costo di accesso ad un elemento in un array.

Signup and view all the flashcards

Tempo di accesso lista concatenata

Costo di accesso all'i-esimo elemento in una lista.

Signup and view all the flashcards

Vantaggio di memoria liste

Permette di gestire la memoria in modo dinamico, usando solo quella necessaria, a differenza degli array che allocano memoria fissa.

Signup and view all the flashcards

newStack(void)

Crea un nuovo stack vuoto.

Signup and view all the flashcards

emptyStack(stack s)

Verifica se lo stack è vuoto.

Signup and view all the flashcards

pop(stack s)

Rimuove l'elemento in cima allo stack.

Signup and view all the flashcards

push(item val, stack s)

Aggiunge un elemento in cima allo stack.

Signup and view all the flashcards

top(stack s)

Restituisce l'elemento in cima allo stack senza rimuoverlo.

Signup and view all the flashcards

MAXSTACK

Dimensione massima dello stack (implementazione array).

Signup and view all the flashcards

Parentesi bilanciate

Controlla se un'espressione aritmetica ha parentesi bilanciate.

Signup and view all the flashcards

corrisp(char a, char b)

Verifica la corrispondenza tra parentesi aperte e chiuse.

Signup and view all the flashcards

verifica(char *expr)

Funzione per verificare se le parentesi sono bilanciate.

Signup and view all the flashcards

Stack senza dimensione max

Implementazione dello stack senza limite di dimensione.

Signup and view all the flashcards

newBtree(void)

Funzione per creare un nuovo albero binario vuoto.

Signup and view all the flashcards

emptyBtree(Btree T)

Funzione per controllare se un albero binario è vuoto.

Signup and view all the flashcards

getRoot(Btree T)

Funzione che restituisce la radice dell'albero binario.

Signup and view all the flashcards

consBtree(item val, Btree sx, Btree dx)

Funzione per costruire un nuovo albero binario con radice 'val', sottoalbero sinistro 'sx' e sottoalbero destro 'dx'.

Signup and view all the flashcards

figlioSX(Btree T)

Funzione per ottenere il sottoalbero sinistro di un nodo.

Signup and view all the flashcards

figlioDX(Btree T)

Funzione per ottenere il sottoalbero destro di un nodo.

Signup and view all the flashcards

Visita di un albero

Esaminare ogni nodo di un albero una e una sola volta.

Signup and view all the flashcards

newList(void)

Crea una nuova lista vuota.

Signup and view all the flashcards

emptyList(list l)

Verifica se una lista è vuota. Restituisce 1 se è vuota, 0 altrimenti.

Signup and view all the flashcards

tailList(list l)

Restituisce la lista senza il primo elemento.

Signup and view all the flashcards

consList(item val, list l)

Aggiunge un elemento all'inizio della lista.

Signup and view all the flashcards

getFirst(list l)

Restituisce il primo elemento della lista.

Signup and view all the flashcards

sizeList(list l)

Restituisce il numero di elementi nella lista.

Signup and view all the flashcards

posItem(list l, item val)

Restituisce la posizione della prima occorrenza di un elemento nella lista, o -1 se non presente.

Signup and view all the flashcards

searchItem(list l, item e)

Ricerca un elemento nella lista e restituisce true se trovato, false altrimenti.

Signup and view all the flashcards

removeItem(list l, item e)

Elimina la prima occorrenza di un elemento dalla lista.

Signup and view all the flashcards

STARTSIZE

Dimensione iniziale dello stack nell'allocazione dinamica.

Signup and view all the flashcards

ADDSIZE

Quantità di memoria aggiuntiva allocata quando lo stack è pieno.

Signup and view all the flashcards

emptyList(l)

Verifica se una lista è vuota.

Signup and view all the flashcards

getFirst(l)

Restituisce il primo elemento di una lista.

Signup and view all the flashcards

tailList(l)

Restituisce la lista senza il primo elemento.

Signup and view all the flashcards

posItem(l, val)

Trova la posizione di un elemento 'val' in una lista 'l'. Restituisce -1 se non trovato.

Signup and view all the flashcards

posItem (vers.Ricorsiva)

Trova la posizione di un elemento in una lista in modo ricorsivo. Restituisce -1 se non trovato.

Signup and view all the flashcards

getItem(l, pos)

Restituisce l'elemento alla posizione 'pos' nella lista 'l'. Restituisce NULLITEM se la posizione non è valida.

Signup and view all the flashcards

reverseList(l)

Restituisce una nuova lista con gli elementi in ordine inverso.

Signup and view all the flashcards

newList()

Crea una nuova lista vuota.

Signup and view all the flashcards

consList(val, l)

Aggiunge un elemento 'val' all'inizio della lista 'l'.

Signup and view all the flashcards

outputList(l)

Stampa gli elementi di una lista 'l' con la loro posizione.

Signup and view all the flashcards

Cos'è una Coda (Queue)?

Tipo di dato astratto (ADT) che segue il principio FIFO (First In, First Out).

Signup and view all the flashcards

Cos'è queue (typedef)?

Definisce la struttura di una coda, spesso tramite un puntatore a una struct c_queue.

Signup and view all the flashcards

Cosa fa newQueue()?

Inizializza una nuova coda vuota.

Signup and view all the flashcards

Cosa fa emptyQueue(queue q)?

Verifica se la coda è vuota.

Signup and view all the flashcards

Cosa fa dequeue(queue q)?

Rimuove e restituisce l'elemento in testa alla coda (FIFO).

Signup and view all the flashcards

Cosa fa enqueue(item val, queue q)?

Aggiunge un elemento alla fine della coda.

Signup and view all the flashcards

Valore di ritorno di enqueue?

Restituisce 1 se l'inserimento ha successo, 0 se fallisce (es. coda piena), -1 in caso di errore (es. coda nulla).

Signup and view all the flashcards

Coda con lista concatenata

Implementazione della coda utilizzando una lista concatenata.

Signup and view all the flashcards

Coda con array

Implementazione della coda utilizzando un array di dimensione fissa con indici head e tail.

Signup and view all the flashcards

Operatore % in coda array

Gestione circolare degli indici head e tail per riutilizzare lo spazio dell'array quando un elemento viene rimosso.

Signup and view all the flashcards

posItem (iterativa)

Implementazione iterativa di posItem per trovare la posizione di un elemento.

Signup and view all the flashcards

posItem (ricorsiva)

Implementazione ricorsiva di posItem per trovare la posizione di un elemento.

Signup and view all the flashcards

reverseList

Inverte l'ordine degli elementi in una lista, creando una nuova lista.

Signup and view all the flashcards

outputList

Mostra gli elementi di una lista, indicando la loro posizione corrente.

Signup and view all the flashcards

Cos'è uno Stack (Pila)?

Struttura dati che segue il principio LIFO (Last In, First Out).

Signup and view all the flashcards

Cos'è 'stack' (tipo)?

Rappresenta l'insieme delle sequenze di elementi di un certo tipo. Può anche essere vuoto (nil).

Signup and view all the flashcards

newStack()

Crea un nuovo stack vuoto.

Signup and view all the flashcards

push(item, stack)

Aggiunge un elemento in cima allo stack.

Signup and view all the flashcards

Stack con array

Implementazione di uno stack con array e un indice 'top' che tiene traccia della cima.

Signup and view all the flashcards

Ordinamento di un array

Processo di ordinamento di un array di dati.

Signup and view all the flashcards

Astrazione sui dati

Definizione completa di un dato e delle operazioni possibili su di esso, indipendentemente dall'implementazione.

Signup and view all the flashcards

Astrazione sul controllo

Definizione completa di un meccanismo di controllo, utilizzabile indipendentemente dalla sua implementazione.

Signup and view all the flashcards

Information Hiding

Nascondere i dettagli implementativi di una struttura dati, rendendoli inaccessibili dall'esterno.

Signup and view all the flashcards

Information hiding

Definire e imporre vincoli di inaccessibilità ai dettagli implementativi.

Signup and view all the flashcards

Interfaccia (di un modulo)

Definisce le risorse ed i servizi messi a disposizione dei clienti.

Signup and view all the flashcards

Cos'è 'a' nel main?

Array di punti.

Signup and view all the flashcards

Cosa fa input_punti?

Richiede all'utente di inserire le coordinate x e y per ciascun punto.

Signup and view all the flashcards

Cosa fa coppie_vicine?

Calcola quante coppie di punti sono a una distanza inferiore a 'd'.

Signup and view all the flashcards

Cosa fa creaPunto?

Alloca dinamicamente memoria per un punto.

Signup and view all the flashcards

Cosa fa distanza(p1, p2)?

Calcola la distanza euclidea tra due punti.

Signup and view all the flashcards

Cos'è punto?

Struttura dati che raggruppa le coordinate x e y di un punto.

Signup and view all the flashcards

Cos'è typedef struct pto *punto?

Dichiarazione di un tipo puntatore a una struttura pto.

Signup and view all the flashcards

Cosa fa CreaVettore?

Creare un vettore con n elementi

Signup and view all the flashcards

Cosa fa LeggiVettore?

Leggere l’elemento di posizione i del vettore

Signup and view all the flashcards

Cosa fa ScriviVettore?

Modifica l’elemento in posizione i del vettore

Signup and view all the flashcards

Cos'è un modulo?

Unità di codice che implementa astrazioni funzionali e fornisce funzioni tramite un'interfaccia.

Signup and view all the flashcards

Cosa fa #include?

Direttiva del precompilatore per includere il contenuto di un file header nel file corrente.

Signup and view all the flashcards

Cos'è un header file?

File che contiene le dichiarazioni (prototipi) delle funzioni e le dichiarazioni di tipi esportati da un modulo.

Signup and view all the flashcards

Cos'è 'information hiding'?

Nascondere i dettagli implementativi di un modulo, esponendo solo l'interfaccia necessaria.

Signup and view all the flashcards

Cosa sono i commenti?

Parole all'interno del codice, utilizzate per documentare il programma. Non influenzano l'esecuzione.

Signup and view all the flashcards

Cosa fa scambia(int *x, int *y)?

Funzione che scambia i valori di due variabili intere puntate da x e y.

Signup and view all the flashcards

Cos'è un modulo client?

Un modulo che utilizza le risorse e i servizi forniti da un altro modulo (modulo server).

Signup and view all the flashcards

Cos'è una 'dichiarazione locale static'?

Dichiarazione di una funzione accessibile solo all'interno del file dove è definita.

Signup and view all the flashcards

item

Tipo di dato generico per gli elementi dello stack.

Signup and view all the flashcards

Valore di ritorno di push/pop

Indica se l'operazione di push o pop ha avuto successo (1) o è fallita (0).

Signup and view all the flashcards

Bilanciamento parentesi

Algoritmo per verificare il corretto abbinamento di simboli di apertura e chiusura.

Signup and view all the flashcards

top (stack)

Variabile che punta alla posizione successiva libera nello stack.

Signup and view all the flashcards

Semplificazione espressione

Estrazione dei soli caratteri di parentesi per semplificare l'analisi.

Signup and view all the flashcards

Lista vuota

Una sequenza senza elementi.

Signup and view all the flashcards

Lista (ADT)

Struttura dati a dimensione variabile che memorizza una sequenza di elementi, accedibili sequenzialmente.

Signup and view all the flashcards

consList(item, list)

Aggiunge un elemento all'inizio di una lista esistente.

Signup and view all the flashcards

Riferimento ultimo nodo

L'ultimo nodo di una lista concatenata contiene un riferimento speciale.

Signup and view all the flashcards

Accesso elemento lista

Scorrere la lista dal primo all'i-esimo elemento.

Signup and view all the flashcards

Visita in pre-ordine

Visita la radice, poi il sottoalbero sinistro, poi il sottoalbero destro.

Signup and view all the flashcards

Visita in post-ordine

Visita il sottoalbero sinistro, poi il sottoalbero destro, poi la radice.

Signup and view all the flashcards

Visita simmetrica (in-ordine)

Visita il sottoalbero sinistro, poi la radice, poi il sottoalbero destro.

Signup and view all the flashcards

inputBtree()

Funzione per costruire un albero binario ricorsivamente.

Signup and view all the flashcards

Caso base inputBtree()

Verifica se un albero binario è vuoto.

Signup and view all the flashcards

Funzione consBtree()

Aggiunge un nodo radice e costruisce i sottoalberi.

Signup and view all the flashcards

Lista (tipo astratto)

Sequenza di elementi dello stesso tipo con operazioni di aggiunta/rimozione.

Signup and view all the flashcards

Il tipo astratto Lista

È una sequenza di elementi di un determinato tipo, in cui è possibile aggiungere o togliere elementi.

Signup and view all the flashcards

Cosa fa enqueue(item e, queue q)?

Aggiunge un elemento alla fine della coda.

Signup and view all the flashcards

STARTSIZE (stack)

Dimensione iniziale dello stack allocato dinamicamente.

Signup and view all the flashcards

ADDSIZE (stack)

Quantità di memoria aggiuntiva allocata quando lo stack è pieno.

Signup and view all the flashcards

struct c_stack

Struttura dati dello stack allocato dinamicamente.

Signup and view all the flashcards

newStack() (array)

Alloca memoria per un nuovo stack e lo inizializza.

Signup and view all the flashcards

push(item val, stack s) (array)

Aggiunge un elemento in cima allo stack. Rialloca memoria se necessario.

Signup and view all the flashcards

realloc(s->vet, ...)

Riadatta dinamicamente la dimensione dello stack.

Signup and view all the flashcards

pop(stack s) (array)

Rimuove l'elemento in cima allo stack.

Signup and view all the flashcards

top(stack s) (array)

Restituisce l'elemento in cima allo stack senza rimuoverlo.

Signup and view all the flashcards

newStack() (lista)

Crea un nuovo stack (implementazione con liste collegate).

Signup and view all the flashcards

Specifica (astrazione dati)

Descrizione di un nuovo tipo di dati e delle operazioni applicabili.

Signup and view all the flashcards

Realizzazione (astrazione dati)

Mostra come i nuovi dati e le operazioni sono implementati usando tipi e operazioni esistenti.

Signup and view all the flashcards

Specifica sintattica

Definisce i nomi dei tipi di dati usati e le firme delle operazioni.

Signup and view all the flashcards

Specifica semantica

Definisce i valori del tipo di dato e le funzioni associate agli operatori, incluse precondizioni e postcondizioni.

Signup and view all the flashcards

Precondizione

Condizione che deve essere vera prima che un operatore possa essere applicato.

Signup and view all the flashcards

Postcondizione

Condizione che è vera dopo che un operatore è stato applicato, se la precondizione era soddisfatta.

Signup and view all the flashcards

Tipo di dato astratto libro

Un insieme di quadruple (autore, titolo, editore, anno), dove autore, titolo e editore sono stringhe e anno è un intero.

Signup and view all the flashcards

creaLibro(stringa, stringa, stringa, intero) -> libro

Un operatore che crea una nuova istanza del tipo di dato libro a partire da stringhe e un intero.

Signup and view all the flashcards

autore(libro) -> stringa

Operatore che restituisce l'autore di un libro.

Signup and view all the flashcards

Effetto Postcondizioni invarianti

Gli operatori non modificano lo stato dell'oggetto libro.

Signup and view all the flashcards

Study Notes

Ottimo lavoro con gli appunti di studio! Ecco le modifiche e le aggiunte basate sul un nuovo testo fornito:

Operazioni: deleteNode() (Implementazione in C)

  • La funzione deleteNode() rimuove un nodo specificato item elem da un albero binario di ricerca BST T, l'implementazione è ricorsiva.
  • Gestisce diversi casi: nodo foglia, nodo con un solo figlio o nodo con entrambi i figli.
  • L'implementazione comporta la ricerca e la sostituzione con il successore in ordine (elemento più piccolo nel sottoalbero destro) o il predecessore in ordine (elemento più grande nel sottoalbero sinistro).
  • Se il nodo da eliminare è vuoto, la funzione restituisce la radice senza modifiche.
  • Se la chiave da eliminare è minore della radice, si prosegue a sinistra, altrimenti, se è maggiore, si prosegue a destra.
  • Se la chiave corrisponde alla radice, ci sono tre casi: il successore in ordine prende il posto della radice.
  • Se il nodo ha un figlio destro \Sinistro allora diventa suo erede

Header File BST.h (Struttura e Prototipi)

  • Definisce la struttura di base per un albero binario di ricerca.
  • Include typedef struct node *BST.
  • Include prototipi per funzioni cruciali come creazione, controllo dello stato vuoto, accesso ai figli e operazioni di inserimento/cancellazione.
  • Le funzioni lavorano su un tipo BST (puntatore a nodo).

Realizzazione del modulo BST (file BST.c)

  • La funzione newBST crea un nuovo albero BST vuoto, restituisce NULL.
  • Funzione emptyBST che controlla se un albero BST è vuoto, restituisce T == NULL.
  • La funzione ricorsiva contains verifica la presenza di un elemento, controllando se T == NULL, se coincide con la radice, o se è minore/maggiore, spostandosi nel sottoalbero appropriato.
  • Le funzioni insert e deleteNode sono dichiarate ma la loro implementazione è presentata in seguito.
  • Le funzioni getItem e setItem permettono rispettivamente di ottenere e impostare il valore di un nodo.

Realizzazione di insert() e creaFoglia() (Implementazione in C)

  • La funzione insert utilizza creaFoglia se l'albero è vuoto, creando un nuovo nodo foglia con l'elemento.
  • Altrimenti, ricorsivamente inserisce il nodo a destra o a sinistra del nodo attuale in base a se il nodo \ elemento è "minore o maggiore".
  • La funzione creaFoglia alloca la memoria per il nuovo nodo foglia, imposta l'elemento, e inizializza i puntatori sinistro e destro a NULL.

Realizzazione di deleteNode() (Implementazione in C)

  • Se il nodo da eliminare è vuoto, la funzione restituisce la radice senza modifiche.
  • Se la chiave da eliminare è minore della radice, si prosegue a sinistra.
  • Altrimenti, se è maggiore, si prosegue a destra.
  • Se la chiave corrisponde alla radice, ci sono tre casi: il successore in ordine prende il posto della radice.
  • Se il nodo ha un figlio destro, allora diventa suo erede.
  • Se il nodo ha entrambi i sottoalberi, si ricerca l'elemento massimo nel sottoalbero sinistro o l'elemento minimo nel sottoalbero destro.

Alberi perfettamente bilanciati e alberi A bilanciati

  • Le operazioni sull'albero di ricerca binaria hanno complessità logaritmica se l'albero è bilanciato.
  • In un albero bilanciato tutti i nodi interni hanno entrambi i sottoalberi e le foglie sono a livello massimo.
  • Se l'albero ha n nodi l'altezza dell'albero è log2 n
  • Un albero di ricerca binaria si dice A bilanciato se per ogni nodo accade che la differenza (in valore assoluto) tra le altezze dei suoi due sottoalberi è minore o uguale a Δ.
  • L'altezza dell'albero bilanciato secondo Δ è △ + log2 n.

Alberi AVL

  • Se il bilanciamento Δ = 1 si parla di alberi AVL
  • Prendono il nome dei loro ideatori: Adel'son, Vel'skii e Landis
  • Per ogni nodo è necessario aggiungere un "indicatore" che può essere -1, 0 o +1
  • L'indicatore -1, se l'altezza del sottoalbero sinistro è maggiore (di 1) dell'altezza del sottoalbero destro
  • L'indicatore è 0, se l'altezza del sottoalbero sinistro è uguale all'altezza del sottoalbero destro.
  • L'indicatore è +1, se l'altezza del sottoalbero sinistro è minore (di 1) dell'altezza del sottoalbero destro.

Ribilanciamento di alberi AVL

  • Un inserimento di una foglia può provocare uno sbilanciamento dell'albero.
  • In tal caso bisogna ribilanciare l'albero con operazioni di rotazione (semplice o doppia) agendo sul nodo x a profondità massima che presenta un non bilanciamento.
  • Tale nodo viene detto nodo critico e si trova sul percorso che va dalla radice al nodo foglia inserito.
  • La rotazione può essere semplice o doppia
  • Considerazioni simili si possono fare anche per la rimozione di un nodo .

Struttura dati: Albero binario (ADT)

  • Operatori: figlioSX, figlioDX e consBtree.
  • Albero binario in se' : puntatore a Nodo ( che e la Root=radice)

Algoritmi di visita

  • void inOrder() visita sotto SX -> getItem( raiz) - sotto DX -> get item radice
  • Le visite di binari (sia in pre-ordine, post-ordine o simmetrica) consistono nel seguire una rotta di viaggio che ne consenta l'esame di ogni nodo una sola volta.
  • Visita in pre-ordine: l'analisi della radice dell'albero e, poi, la visita, effettuata con lo stesso metodo, dei due sottoalberi, prima il sinistro, poi il destro
  • Visita in post-ordine: richiede dapprima la visita, effettuata con lo stesso metodo, dei sottoalberi, prima il sinistro e poi il destro, e, in seguito, l'analisi della radice dell'albero
  • Visita simmetrica: richiede prima la visita del sottoalbero sinistro (effettuata sempre con lo stesso metodo), poi l'analisi della radice, e poi la visita del sottoalbero destro

Realizzazione di code a priorità tramite heap

  • Il codice seguente viene considerate solo le chiavi( key), senza il valore di esse associato cioè numerici
  • Inclusa la Funzione void scendi (PQueue q)
  • Static void sali( PQueue q)

Code a priorita rappresentato da array

  • La struct include Pqueue q, Q == NULL
  • restituisce valore 0 solo in caso fallisca la richiesta ( insert o deleteMax)
  • le altre restituiscono 1 . In Caso positivo

Rimozione code

  • Se l'albero a un entita , nessun problema
  • Se è una solo"" a dx - prende solo il valore
  • Se""e a Sin - Prende solo il valore di Sin
  • Se possiede anche un dx < Prende il valore + Max" Alternativamente prende elemento MINIMO in sottoAll destro"

Alberi binari (Realizzazione)

  • L'insieme di operatori così definiti costituisce minino di un albero E frequente "arricchhire il tipo B con altri operatori"

Alberi (Realizzazione)

  • Gli alberi Binaria sono realizzati tramite "STRUTURA A Punt"
  1. Pointer Sx
  2. Poiunter DX
  3. Etichetta < usa sempre Item>

Algorietmo binaria ( file : Btree)

la visuta a un abero B consiste nel segure una "Rotta di Viaggio" (albero visitato solo 1 volta)

ADT ALbero Binario : Realizazione

  • Realizzazione ADT e' nel file bst con file bst .h" Realizzazione ADT albero e tipo - e " punt" ad etichetta
  • Strut node
  • Int val; Struct pointer_ Sinistro Struct POiter _Dist

< B tree""Punt <<<<N"""""" "" "" "" """

Code implement ad avec file C

//// File item h e implementa la struttura typedef int , e include i parametri //Q perche non abbiamo code in C //PQUeue Code Restituire valore zero “” Solo a CASO FAILS a, altrimenti 1 <<

Liste concatenate>> e "implementabile"" tramite HEEPP"" come da ""Traccia"" e.

*Pile *Implementazione <>

Struct NODE node" ”””””” Item vaue

  • struct*Node right"" - File “H Implementatz”

    • B TREE *” Pointer b tre” L"ADT <Code prioritaria”“e realt in modo ( simple)Item *” “”Val””””” key “”

<“”PQueue Code “”>

  • L-ADT restituire “”Val =""0 (Zero) solo nel""CASO Falli ”””Altrim . 1"",1;

“”

  • Static “”sali “” e “”S""Code” """( pointer QCode<<

“”Queue“” " implement à ad con //// <> “”VET T massim "" ""dimens (SIZE CodeQ ="", pointer Q” ////"Strut (Size of struct ) Pointer To Head ""code Q" Implement Item“”" Restit Q""

C Implementi A C Code * FILE *

  • Restituire () Q head pointer -> Q HEAD """ <> A Strut Item VET

"""" Head

“”Int Queue”""" L""ADT (Code prioritaria""e realt in modo (simple)Item *” “”Val””””” key

""""<P”" + Q ""Code

Con ""Qhead""""<> <>“”Q"" restit <>"" if non ""verificat""""

Pointer to queue code implements Head “”“” int Queue implement a pointer ""val""""<> if != NULL Pointer “””” + ""Implement""

File Item per ""tipoGenerco ""definisce un oggetto ""valuechiave/Key""""

Punt - > head <>Non implemente""""

e con ""Q_head""""

""Realiizazione delle ADTree in Lenguage C

  • Q"" restituisce "", l '' operatoere

Lista strutt""Pointer Code”""" <> Head " “Val

""Val=Val”""" *Strada per Item """Val”""""

Altrimenti=""0"

Code implement implement and code () e” ""C* File *

  • Struttura" Item* Vett “”Massim Q”” ""Size"" Pointer to head (numElem) <> //Pointer strut“”
  • L-ADT <“><Code prioritaria”“e realt in modo (simple)Item *” “”Val””””” key Altrimenti

""<“”PQueue Code”

<> restit Q""""Head Q "" //""Se Q_head """

Code implement

Studying That Suits You

Use AI to generate personalized quizzes and flashcards to suit your learning preferences.

Quiz Team

Related Documents

More Like This

Untitled
44 questions

Untitled

ExaltingAndradite avatar
ExaltingAndradite
Untitled
6 questions

Untitled

StrikingParadise avatar
StrikingParadise
Untitled
48 questions

Untitled

HilariousElegy8069 avatar
HilariousElegy8069
Untitled
121 questions

Untitled

NicerLongBeach3605 avatar
NicerLongBeach3605
Use Quizgecko on...
Browser
Browser