Salta al contenuto
Note per Studenti Formulario - dati e algoritmi

Formulario - dati e algoritmi

In questa pagina 11

Nozioni fondamentali

Note: Problemi computazionali e algoritmiProblema computazionale come insieme di coppie (istanza, soluzione); algoritmo e modello di calcolo RAM; pseudocodice; taglia di un'istanza; ADT e struttura dati concreta; esempio svolto con ricerca lineare e binaria in un array ordinato.Problemi computazionali e algoritmi → · Complessità in tempo e caso pessimoPerché lo studio sperimentale non basta; complessità al caso pessimo come massimo sul numero di operazioni tra le istanze di una data taglia; stima con limiti superiore e inferiore senza trovare l'istanza peggiore; esempi arrayMax, prefixAverages e InsertionSort; efficienza asintotica e limiti dell'analisi.Complessità in tempo e caso pessimo → · Notazione asintoticaDefinizioni di O, Omega, Theta e o piccolo con le costanti c ed n0; esempi con costanti esplicite; proprietà (polinomi, esponenziali, logaritmi, somme, implicazioni tra notazioni); sommatorie notevoli; terminologia (logaritmica, lineare, polinomiale, esponenziale).Notazione asintotica → · Dimostrazioni, induzione e invariantiTecniche di dimostrazione (esempio, controesempio, assurdo), induzione con casi base multipli, invarianti di ciclo (inizializzazione, conservazione, uso alla fine), schema generale per provare la correttezza; esempi svolti su arrayMax, sequenza di bit e numeri di Fibonacci.Dimostrazioni, induzione e invarianti → · Algoritmi ricorsiviAlgoritmi ricorsivi come induzione eseguita; albero della ricorsione e record di attivazione nello stack; esempi ReverseArray, LinearSum, Power in tempo logaritmico, Fibonacci ricorsivo (esponenziale) e con memoizzazione; analisi della complessità con l'albero della ricorsione e correttezza per induzione.Algoritmi ricorsivi →

  • Caso pessimo tA(n)=max⁡{tA,i:i di taglia n}t_A(n)=\max\{t_{A,i}:i\text{ di taglia }n\} nel modello RAMRandom Access Machine: ogni passo elementare costa Θ(1). O(g)O(g): ogni istanza costa ≤c g(n)\le c\,g(n); Ω(g)\Omega(g): esiste un'istanza che costa ≥c g(n)\ge c\,g(n); Θ=O∩Ω\Theta=O\cap\Omega con gg tight e semplice.
  • f∈O(g)f\in O(g): ∃c>0,n0\exists c>0,n_0 con f(n)≤c g(n)f(n)\le c\,g(n) per n≥n0n\ge n_0; f∈o(g)f\in o(g): lim⁡fg=0\lim\frac fg=0. Polinomio di grado kk ∈Θ(nk)\in\Theta(n^k); nk∈o(an)n^k\in o(a^n) (a>1a>1); (log⁡n)k∈o(nh)(\log n)^k\in o(n^h); log⁡bn=log⁡an⋅log⁡ba\log_bn=\log_an\cdot\log_ba; O⇒oO\Rightarrow o e O⇒ΘO\Rightarrow\Theta sono falsi.
  • Sommatorie: ∑i=0ni=n(n+1)2\sum_{i=0}^ni=\frac{n(n+1)}2, ∑i2=n(n+1)(2n+1)6∈Θ(n3)\sum i^2=\frac{n(n+1)(2n+1)}6\in\Theta(n^3), ∑ai=an+1−1a−1\sum a^i=\frac{a^{n+1}-1}{a-1}. In 1 s con operazioni da 1 ns: n≈109n\approx10^9 (lineare), n≈3⋅104n\approx3\cdot10^4 (n2n^2), n≈30n\approx30 (2n2^n).

Grafico interattivo: Crescita di n, n·log₂n, n² e 2ⁿ per n da 1 a 10 (numero di operazioni, asse verticale fino a 100): a n = 10 valgono 10, 33, 100 e 1024; l'esponenziale supera il quadrato già da n = 5 e esce dal grafico a n ≈ 6,6

  • InsertionSort: n(n−1)2\frac{n(n-1)}2 confronti sull'array decrescente (caso pessimo), n−1n-1 sull'ordinato; prefixAverages1 (doppio ciclo) n(n+1)2∈Θ(n2)\frac{n(n+1)}2\in\Theta(n^2) contro prefixAverages2 (somma corrente) Θ(n)\Theta(n).

Grafico interattivo: Confronti di InsertionSort in funzione di n: n(n−1)/2 sull'array decrescente (caso pessimo, 45 per n = 10) e n−1 sull'array già ordinato (caso migliore): la complessità al caso pessimo è quadratica, ma su input ordinato l'algoritmo è lineare

  • Ricerca lineare Θ(n)\Theta(n); binaria O(log⁡n)O(\log n) con mid=⌊lo+hi2⌋mid=\lfloor\frac{lo+hi}2\rfloor e al più ⌊log⁡2n⌋+1\lfloor\log_2n\rfloor+1 iterazioni. Induzione: base Q(n0..n0+k)Q(n_0..n_0+k), passo da Q(m)Q(m) per n0≤m≤nn_0\le m\le n a Q(n+1)Q(n+1). Invariante di ciclo: vale prima, si conserva, a fine ciclo implica la tesi (arrayMax: currMax=max⁡A[0..i]currMax=\max A[0..i]).
  • Ricorsione: costo = somma sui nodi dell'albero della ricorsione, spazio Θ(d)\Theta(d) per profondità dd. Power(x,n) con una sola chiamata: O(log⁡n)O(\log n). Fibonacci ricorsivo: C(n)=1+C(n−1)+C(n−2)=2F(n+1)−1C(n)=1+C(n-1)+C(n-2)=2F(n+1)-1 chiamate, esponenziale; con memoizzazione Θ(n)\Theta(n).

Il linguaggio C

Note: Puntatori, struct e memoria dinamica in CPuntatori e passaggio per riferimento in C, array e aritmetica dei puntatori, stringhe, struct e typedef con l'operatore ->, malloc e free, puntatore a puntatore per modificare una testa; compilazione con Makefile; errori tipici (puntatori pendenti, perdite di memoria, off-by-one).Puntatori, struct e memoria dinamica in C → · Liste concatenate in CLista singolarmente concatenata in C con nodo struct e testa passata per riferimento (Nodo **); addHead, addTail ricorsiva e iterativa, pop, inversione in loco, liberazione; coda con puntatori a testa e coda; ricorsione sulle liste; costi.Liste concatenate in C →

Elemento Sintassi essenziale
Puntatore int *p = &x; *p valore, NULL nessun oggetto; passaggio per valore: per modificare si passa &x
Array v[i] ≡\equiv *(v+i); negli argomenti decade a puntatore (lunghezza a parte), nessun controllo dei limiti
Stringa char[] terminato da '\0'; strcpy, strcmp (mai ==)
Struct typedef struct nodo { int val; struct nodo *next; } Nodo; . su struct, -> su puntatore
Memoria dinamica malloc(n * sizeof(T)) (controllare NULL), un free per ogni malloc; stack = locali, heap = malloc
Puntatore a puntatore Nodo **l per cambiare testa o radice dal chiamante
Compilazione gcc -std=c99 -Wall -Wextra -o p p.c (-lm per la matematica)
  • Lista in C: addHead: aux->next = *l; *l = aux; Θ(1)\Theta(1); addTail ricorsiva su &(*l)->next Θ(n)\Theta(n); pop: salvare val e next, poi free; inversione in loco con prec, cur, succ O(n)O(n). Coda con testa e coda: enqueue e dequeue Θ(1)\Theta(1), aggiornando entrambi quando si svuota.

ADT elementari

Note: Liste, pile e codeRipasso degli ADT elementari: lista index-based (array) e position-based (lista doppiamente concatenata con sentinelle), pila LIFO, coda FIFO, deque, iteratori; interfacce, implementazioni e costi; array estendibile e coda circolare.Liste, pile e code →

Struttura Operazioni e costi
Lista index-based su array get, set O(1)O(1); add(i,e), remove(i) O(n)O(n); inserimento in fondo O(1)O(1) ammortizzato (raddoppio)
Lista position-based (doppia, 2 sentinelle) tutte O(1)O(1), scansione solo sequenziale
Pila (LIFO) push, top, pop O(1)O(1)
Coda (FIFO) enqueue, first, dequeue O(1)O(1) con lista e puntatore alla coda o array circolare: enqueue in (f+size) mod N(f+size)\bmod N, dequeue f←(f+1) mod Nf\leftarrow(f+1)\bmod N

Alberi

Note: AlberiAlbero radicato (definizione per padre e ricorsiva), terminologia (antenati, discendenti, nodi interni ed esterni, sottoalbero, albero ordinato), profondità, livello, altezza; altezza = massima profondità delle foglie; algoritmi depth e height con costo; somma dei figli = n-1; esempio di algoritmo Omega(n^2) (heightBad).Alberi → · Visite di alberiVisite in preorder e postorder come schemi generali (template) da adattare; complessità Theta(n + somma dei costi di visita) perché la somma dei figli è n-1; esempi (indice di un libro, spazio occupato in un file system); profondità con il preorder, altezza con il postorder; antenato comune più basso.Visite di alberi → · Alberi binariAlbero binario e albero binario proprio; interfaccia; relazioni tra nodi, foglie e altezza (m = n-m+1, h+1 <= m <= 2^h, 2h+1 <= n <= 2^(h+1)-1) con dimostrazioni; visita inorder; parse tree e valutazione di espressioni; heightSum come esempio di calcolo di un'informazione più ricca.Alberi binari →

  • depth(r)=0\text{depth}(r)=0, depth(v)=1+depth(padre)\text{depth}(v)=1+\text{depth}(\text{padre}); height(foglia)=0\text{height}(\text{foglia})=0, height(v)=1+max⁡wheight(w)\text{height}(v)=1+\max_w\text{height}(w); height(T)=max⁡{depth(v):v foglia}\text{height}(T)=\max\{\text{depth}(v):v\text{ foglia}\}. height in postorder Θ(n)\Theta(n); heightBad (depth da ogni foglia) Ω(n2)\Omega(n^2).
  • Visite: preorder (nodo, poi figli), postorder (figli, poi nodo); costo Θ(n+∑utu)\Theta(n+\sum_ut_u) perché ∑ucu=n−1\sum_uc_u=n-1. LCA in O(h)O(h). Albero binario proprio (nn nodi, mm foglie, altezza hh): m=n−m+1m=n-m+1, h+1≤m≤2hh+1\le m\le2^h, 2h+1≤n≤2h+1−12h+1\le n\le2^{h+1}-1, log⁡2(n+1)−1≤h≤n−12\log_2(n+1)-1\le h\le\frac{n-1}2. Inorder in un ABR dà le chiavi crescenti.

Grafico interattivo: Altezza h di un albero binario proprio con n nodi: per ogni n sta tra log₂(n + 1) − 1 (albero perfetto, minimo) e (n − 1)/2 (albero a pettine, massimo); con n = 15 vale tra 3 e 7

Code con priorità e heap

Note: Code con prioritàEntry chiave-valore; ADT coda con priorità (insert, min, removeMin) con chiave minima = priorità massima; esempio di esecuzione; applicazioni; implementazioni con lista non ordinata e ordinata e relativi costi; ordinamento tramite coda con priorità.Code con priorità → · HeapAlbero binario completo e sua altezza floor(log2 n); heap = albero completo con heap-order property; proprietà (radice minima, cammini non decrescenti); rappresentazione su array con level numbering; insert con up-heap bubbling, removeMin con down-heap bubbling, rimozione di una entry qualsiasi; invarianti e costi Theta(log n); esempio svolto.Heap → · Costruzione di uno heapCostruire uno heap da un array di n entry: approccio top-down con n-1 insert, Theta(n log n); approccio bottom-up con down-heap dalle foglie verso la radice, Theta(n), con dimostrazione della somma; esempi svolti, in loco; unione di due alberi con heap-order.Costruzione di uno heap →

Implementazione insert min removeMin Ordinamento
Lista non ordinata Θ(1)\Theta(1) Θ(n)\Theta(n) Θ(n)\Theta(n) selection sort Θ(n2)\Theta(n^2)
Lista ordinata Θ(n)\Theta(n) Θ(1)\Theta(1) Θ(1)\Theta(1) insertion sort Θ(n2)\Theta(n^2)
Heap Θ(log⁡n)\Theta(\log n) Θ(1)\Theta(1) Θ(log⁡n)\Theta(\log n) heap sort Θ(nlog⁡n)\Theta(n\log n)
  • Heap = albero completo con key(v)≥key(padre)\text{key}(v)\ge\text{key}(\text{padre}); h=⌊log⁡2n⌋h=\lfloor\log_2n\rfloor. Array P[1..n]P[1..n]: figli 2i,2i+12i,2i+1, padre ⌊i2⌋\lfloor\frac i2\rfloor, last=n\text{last}=n. insert in P[last+1]P[\text{last}+1] poi up-heap; removeMin: P[1]←P[last]P[1]\leftarrow P[\text{last}], last−−\text{last}--, down-heap col figlio minore; removeEntry: up-heap o down-heap.
  • Costruzione: top-down (up-heap per j=2..nj=2..n) Θ(nlog⁡n)\Theta(n\log n); bottom-up (down-heap per j=⌊n2⌋..1j=\lfloor\frac n2\rfloor..1) Θ(n)\Theta(n) perché ∑ℓ=1hℓ2ℓ<2\sum_{\ell=1}^h\frac\ell{2^\ell}<2.

Grafico interattivo: Scambi al caso peggiore nella costruzione di uno heap con n elementi: top-down su array decrescente, (n+1)·⌊log₂n⌋ − 2^(⌊log₂n⌋+1) + 2 (34 per n = 15, 258 per n = 63, 1538 per n = 255), bottom-up al più n − 1 (somma delle altezze dei nodi: 11, 57 e 247 se n = 2^k − 1)

Mappe e tabelle hash

Note: Mappe e dizionariADT mappa (chiavi distinte) con get, put, remove, keySet/values/entrySet; famiglia mappa/mappa ordinata/dizionario (multimappa); applicazioni; implementazioni semplici ma poco efficienti (lista, array indicizzato dalle chiavi); dizionario realizzato con una mappa di liste.Mappe e dizionari → · Tabelle hashTabella hash per implementare una mappa: funzione hash = hash code + compression function, bucket array, separate chaining; hash code per numeri e stringhe (polynomial, cyclic shift), division e MAD; load factor, complessità al caso pessimo Theta(n) e medio O(1+lambda), rehashing; esempio svolto con inserimenti e collisioni.Tabelle hash →

  • Mappa: get(k), put(k,v) (restituisce il vecchio valore o null), remove(k); lista non ordinata Θ(n)\Theta(n), array indicizzato dalle chiavi Θ(1)\Theta(1) ma spazio Θ(∣U∣)\Theta(|U|). Dizionario: chiavi ripetute, remove(k,v) costa s=∣Lk∣s=|L_k| in più.
  • Hash: hh = hash code + compressione. Divisione i mod Ni\bmod N (NN primo); MAD [(ai+b) mod p] mod N[(ai+b)\bmod p]\bmod N con p>Np>N primo; stringhe: polinomiale ∑siak−1−i\sum s_ia^{k-1-i} (a=31a=31). Concatenamento separato con λ=nN\lambda=\frac nN: caso pessimo Θ(n)\Theta(n), medio O(1+λ)O(1+\lambda) sotto uniform hashing; rehashing se λ\lambda supera una soglia (es. 0,750{,}75): N′≥2NN'\ge2N, nuova hh, reinserimento in Θ(n)\Theta(n) ammortizzato.

Grafico interattivo: Costo atteso di get, put e remove in una tabella hash con concatenamento separato sotto uniform hashing, O(1 + λ) in funzione del fattore di carico λ = n/N: il rehashing scatta oltre una soglia, per esempio 0,75

Alberi di ricerca

Note: Alberi binari di ricercaAlbero binario di ricerca come albero binario proprio con entry nei nodi interni e foglie vuote; inorder crescente; TreeSearch; get, put e remove (due casi, con predecessore inorder) in Theta(h); altezza fino a n-1; esempi di inserimenti; alberi aumentati con campi size e max e algoritmi di conteggio e interrogazione in O(h).Alberi binari di ricerca → · Multi-way search tree e alberi (2,4)Multi-way search tree (nodi con più entry, d figli e d-1 chiavi ordinate), ricerca in O(d_max h), un MWS tree con n entry ha n+1 foglie; albero (2,4): nodi con 2-4 figli e tutte le foglie alla stessa profondità, altezza Theta(log n) con dimostrazione, operazioni in Theta(log n); idea di overflow e underflow; tabella di confronto con gli alberi binari di ricerca.Multi-way search tree e alberi (2,4) →

Struttura get, put, remove Altezza
ABR Θ(h)\Theta(h) h≤n−1h\le n-1, Θ(n)\Theta(n) al caso pessimo
Albero (2,4) Θ(log⁡n)\Theta(\log n) 12log⁡2(n+1)≤h≤log⁡2(n+1)\frac12\log_2(n+1)\le h\le\log_2(n+1)
Tabella hash O(1+λ)O(1+\lambda) in media, Θ(n)\Theta(n) al caso pessimo non ordinata
  • ABR: sinistra << chiave << destra; nn entry ⇒\Rightarrow nn nodi interni e n+1n+1 foglie. remove con due figli interni: si copia l'entry del predecessore inorder (massimo del sottoalbero sinistro) e si elimina quel nodo. Multi-way: dd-nodo con d−1d-1 chiavi, MWTreeSearch O(dmaxh)O(d_{max}h). (2,4): 2-4 figli e foglie tutte alla stessa profondità; overflow (5-nodo) si spezza e la terza chiave sale.

Grafico interattivo: Altezza di un albero (2,4) con n entry: tra ½·log₂(n + 1) e log₂(n + 1), quindi Θ(log n); un albero binario di ricerca sbilanciato può invece arrivare a n − 1 (qui fuori scala per n grande)

Alberi e heap in C

Note: Alberi e heap in CAlbero binario in C con nodo struct e figli left/right; funzioni ricorsive (conteggio, altezza, visita inorder, liberazione in postorder); inserimento in un albero binario di ricerca con Nodo **; min-heap su array con indici da 1 (insert, removeMin, bottomUp).Alberi e heap in C →

  • Nodo struct nodo { int val; struct nodo *left, *right; }; altezza con NULL →−1\to-1 e 1 + max(altezza(left), altezza(right)); liberaAlbero in postorder; addBST(Nodo **r, v) Θ(h)\Theta(h). Heap su array da indice 1 con last passato per puntatore: insert (while (i > 1 && h[i/2] > h[i]) scambia) Θ(log⁡n)\Theta(\log n), downHeap (while (2*i <= last)), bottomUp da last/2 a 1 in Θ(n)\Theta(n).

Algoritmi di ordinamento

Note: Algoritmi di ordinamentoSelection sort e insertion sort (quadratici, con invarianti), merge sort (divide et impera, Theta(n log n)), quick sort (caso pessimo quadratico, medio n log n), heap sort (in loco, Theta(n log n)), ordinamento senza confronti per chiavi intere in un intervallo piccolo, limite inferiore Omega(n log n) per gli algoritmi basati su confronti.Algoritmi di ordinamento →

Algoritmo Pessimo Migliore / atteso Note
Selection sort n(n−1)2\frac{n(n-1)}2 sempre, Θ(n2)\Theta(n^2) Θ(n2)\Theta(n^2) invariante: S[0..i−1]S[0..i-1] = i minimi ordinati
Insertion sort Θ(n2)\Theta(n^2) Θ(n)\Theta(n) (già ordinato) S[0..i−1]S[0..i-1] ordinato
Merge sort Θ(nlog⁡n)\Theta(n\log n) Θ(nlog⁡n)\Theta(n\log n) spazio Θ(n)\Theta(n)
Quick sort Θ(n2)\Theta(n^2) (pivot minimo o massimo) atteso O(nlog⁡n)O(n\log n) partizione in loco Θ(n)\Theta(n)
Heap sort Θ(nlog⁡n)\Theta(n\log n) Θ(nlog⁡n)\Theta(n\log n) O(1)O(1) spazio
Conteggio (interi in [0,K][0,K]) Θ(n+K)\Theta(n+K) senza confronti
  • Limite inferiore per i confronti: albero di decisione con ≥n!\ge n! foglie, altezza ≥log⁡2n!≥n2log⁡2n2\ge\log_2n!\ge\frac n2\log_2\frac n2, quindi Ω(nlog⁡n)\Omega(n\log n); merge sort e heap sort sono ottimi.

Grafico interattivo: Confronti al caso pessimo in funzione di n: selection sort e insertion sort fanno n(n−1)/2, il merge sort n·log₂n − n + 1 (esatto per n potenza di 2); a n = 64 sono 2016 contro 321, mentre l'insertion sort su un array già ordinato ne fa solo n − 1 = 63

Grafi: definizioni e visite

Note: Grafi - definizioni e proprietàGrafo G=(V,E) diretto e non diretto, grafo semplice e pesato; incidenza, adiacenza, grado; cammini, cicli, sottografi, grafi connessi e componenti connesse; alberi liberi, foreste, spanning tree e spanning forest; proprietà con dimostrazioni (somma dei gradi = 2m, m <= n(n-1)/2, alberi m = n-1, connessi m >= n-1, foreste m <= n-1).Grafi - definizioni e proprietà → · Rappresentazione dei grafiStrutture di base (lista dei vertici LV, lista degli archi LE), liste di adiacenza, matrice di adiacenza; operazioni incidentEdges, opposite, areAdjacent; spazio e tempi a confronto; esempio con un grafo di 5 vertici.Rappresentazione dei grafi → · Visite di grafi - BFS e DFSVisite in ampiezza (BFS) e in profondità (DFS) come design pattern; etichette discovery, cross e back edge; BFS tree e distanze; complessità Theta(n+m) con liste di adiacenza; applicazioni (connettività, componenti, spanning tree, cammini minimi non pesati, cicli, vertici a distanza al più d); esempio svolto su un grafo di 7 vertici.Visite di grafi - BFS e DFS →

  • G=(V,E)G=(V,E), n=∣V∣n=|V|, m=∣E∣m=|E| (semplice non diretto). P1 ∑degree(v)=2m\sum\text{degree}(v)=2m; P2 m≤(n2)m\le\binom n2; P3 albero m=n−1m=n-1; P4 connesso m≥n−1m\ge n-1; P5 foresta m≤n−1m\le n-1. Spanning forest con kk componenti: n−kn-k archi.

Grafico interattivo: Numero di archi m di un grafo semplice non diretto connesso con n vertici: almeno n − 1 (albero, P4) e al più n(n − 1)/2 (grafo completo, P2); un albero ha esattamente n − 1 archi (P3)

Operazione Solo lista archi Liste di adiacenza Matrice di adiacenza
Spazio Θ(n+m)\Theta(n+m) Θ(n+m)\Theta(n+m) Θ(n2)\Theta(n^2)
incidentEdges(v) Θ(m)\Theta(m) Θ(degree(v))\Theta(\text{degree}(v)) Θ(n)\Theta(n)
areAdjacent(u,v) Θ(m)\Theta(m) Θ(min⁡(deg⁡u,deg⁡v))\Theta(\min(\deg u,\deg v)) Θ(1)\Theta(1)
  • BFS: livelli Li+1L_{i+1} = nuovi vicini di LiL_i, archi DISCOVERY/CROSS; v∈Li⇒d(s,v)=iv\in L_i\Rightarrow d(s,v)=i. DFS: archi DISCOVERY/BACK, cammini non minimi. Costo Θ(n+m)\Theta(n+m) con liste di adiacenza (ogni arco visto due volte); per grafi non connessi si rilancia da ogni vertice con ID = 0. Con la BFS: connettività, componenti, spanning tree, cammino minimo con parent.

Cammini minimi, alberi di copertura e ordinamento topologico

Note: Cammini minimi e algoritmo di DijkstraGrafi pesati, lunghezza di un cammino e distanza; sottocammini di un cammino minimo; problema SSSP; algoritmo di Dijkstra con cloud e priority queue, rilassamento degli archi, esempio svolto; correttezza (due lemmi) e complessità O(min(n^2, (n+m) log n)) con lista non ordinata o heap; pesi non negativi.Cammini minimi e algoritmo di Dijkstra → · Minimum spanning treeMinimum spanning tree di un grafo pesato connesso; proprietà del taglio (cut property) con dimostrazione; algoritmo di Kruskal con partizioni (union-find) e algoritmo di Prim con coda con priorità; esempio svolto sullo stesso grafo di Dijkstra; complessità O(m log n).Minimum spanning tree → · Grafi diretti e ordinamento topologicoGrafi diretti (archi orientati, grado entrante e uscente, cammini e cicli diretti), visite su grafi diretti e tipi di archi; DAG; ordinamento topologico con l'algoritmo basato sui gradi entranti e con la DFS (reverse postorder), correttezza e costo Theta(n+m); esempio svolto.Grafi diretti e ordinamento topologico →

Algoritmo Idea Costo
Dijkstra (pesi ≥0\ge0) removeMin di uu da QQ (chiave v.D) e rilassamento: se u.D + w(u,v) < v.D aggiorna v.D e v.parent O((n+m)log⁡n)O((n+m)\log n) con heap, O(n2)O(n^2) con lista non ordinata, O(min⁡{n2,(n+m)log⁡n})O(\min\{n^2,(n+m)\log n\})
Prim come Dijkstra con v.D <- w(u,v) O((n+m)log⁡n)O((n+m)\log n) con heap, O(n2)O(n^2) con lista
Kruskal archi per peso crescente, si aggiunge ee se collega due componenti diverse (union-find) O(mlog⁡n)O(m\log n)
Ordine topologico coda dei vertici con grado entrante 0 oppure reverse postorder della DFS Θ(n+m)\Theta(n+m)
  • MST: spanning tree di peso minimo, n−1n-1 archi; proprietà del taglio: l'arco minimo che attraversa un taglio non attraversato da F⊆F\subseteq MST può essere aggiunto. Cammini minimi: sottocammini di cammini minimi sono minimi; pesi tutti 1 ⇒\Rightarrow BFS. Ordine topologico: per ogni (u→v)(u\to v), uu prima di vv; esiste   ⟺  \iff DAG   ⟺  \iff nessun back edge; con ordine di meno di nn vertici c'è un ciclo.

Versione ripasso