Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
Definizione di albero con radice ordinato
Un albero con radice ordinato è un albero con radice in cui ogni classe di equivalenza (rispetto alla relazione "essere fratello di") è totalmente ordinata.
Definizione di albero binario
Un albero binario è un albero con radice ordinato in cui:
- I nodi possono avere al massimo 2 figli
- I figli di un nodo sono distinti come figlio sinistro e figlio destro
Definizioni
- Pieno: Un albero binario si dice pieno se tutti i livelli sono saturi tranne eventualmente l'ultimo
- Completo: Un albero binario si dice completo se è pieno e i nodi sull'ultimo livello sono tutti disposti il più a sinistra possibile
Proprietà Matematiche
FATTO: Un albero binario completo di altezza h ha un numero di nodi che soddisfa la relazione h+1 ≤ n ≤ 2^h - 1. Di conseguenza, l'altezza di un albero binario completo con n nodi soddisfa la relazione h ~ log n.
- Un albero binario si dice degenere se ha nodi e altezza n-1 ⇒ n
- DEFINIZIONE Un albero binario localmente completo è un albero in cui ogni nodo ha 0 o 2 figli
- Teorema n(n + 1) Un albero binario localmente completo con n nodi interni ha n + 1 foglie
- Dimostrazione per induzione
- Caso Base: 0 nodi interni, 1 foglia (la radice)
- Induzione: tolta la radice rimangono k nodi interni, nel sottoalbero sinistro e n - k nodi interni nel sottoalbero destro. Per il numero totale di foglie è ((k - 1) + 1) + ((n - k) + 1) = n - 1
- Teorema n LC = LC + 2n In un albero binario localmente completo con n nodi interni vale la relazione
- Dimostrazione Ogni albero si può ottenere partendo da un albero formato dalla sola radice e iterando un processo che seleziona una foglia e la trasforma in nodo interno. Inizialmente si ha LC = 0, k = 0. LC := LC + k. Quando si trasforma una foglia
di livello si ha mentree i i iLC := LC − k + 2(k + 1) = LC + k + 2 n LC = LC + 2n. Dopo passi si hae e e e i12- Visita di GrafiPROBLEMA [ Attraversamento in Ampiezza ]⟨V, ⟩G = E s ∈ VInput : ( non orientato e connesso ) e sOutput : una sequenza che contiene tutti i nodi del grafo, ordinati rispetto alla distanza dapublic void Ampiezza(s){Queue<Nodo> q=new Queue<Nodo>();List<Lato> u=new List<Lato>();q.enqueue(s);nuovo[s]=0;for (v in V) if (v!=s) nuovo[v]=1;while (!q.isEmpty()){v = q.front();q.dequeue();v.visita();for (w in Lista di adiacenza di v)if (nuovo[w]){nuovo[w]=0;q.enqueue(w);u.Insert({v,w},1);}}} fi 10 di 3213- Visita di AlberiDEFINIZIONE ALTERNATIVA⟨r⟩• ( la radice è una foglia ) è un albero con radice ordinato ⟨ ⟩T , T , . . . , T r r, T , T , . . . , TSe sono alberi con radice ordinati e è un nodo allora è un• 1 2 m 1 2 malbero con radice ordinatoMetodi di attraversamento:•
Preorder• Postorder ⇒• Levelorder Attraversamento in Ampiezza• Solo per gli alberi binari c’è anche il metodo Inorder Complessità: TPer ogni strategia di visita a un albero vale che: • Ogni nodo di è parametro attuale di una e una sola chiamata ricorsivi • Ogni nodo di viene visitato una e una sola volta T O(1) O(1) • Per ogni nodo di visitato si e ettuano operazioni di costo Di conseguenza: Θ(n) Tempo di calcolo : O(n) n Complessità in spazio : ( Lo stack per supportare la ricorsione al massimo contiene O(1)record di attivazione ciascuno dei quali occupa spazio ) 14- Visita Iterativa di Alberi PreOrder Iterativoprivate void preOrdIt(Node r) { Stack<Node> s = new Stack<Node>(); if (r!=NULL) s.push(r); while (!s.is_empty()) { r=s.top(); s.pop(); r.visit(); if (r.dx != null) s.push(r.dx); if (r.sx != null) s.push(r.sx); } }
InOrder Iterativoprivate void inOrderIt(Node r){ Stack<Node> s = new Stack<Node>(); if (r!=NULL) s.push(r); while (!s.is_empty()) { while (r!=NULL) { s.push(r); r = r.sx; } r = s.top(); s.pop(); r.visit(); r = r.dx; } }
(r!=NULL) s.push(r); while(!s.isEmpty()){ r=s.top(); s.pop(); while(r!=null) { s.push(r); r=r.sx; } if (!s.is_Empty()){ r=s.top(); s.pop(); r.visit(); r=r.dx; s.push(r); } } ff 11 di 3215- Il Problema dell’ordinamento Siano: U• un insieme di elementi≤ ⊆ U × U U • relazione d’ordine totaleuna su ( Ri essiva, Transitiva, Antisimmetrica ) Problema dell’ordinamento: nX ∈ U Input : X X [i ] ≤ X [i + 1] ∀1 ≤ i ≤ n Output : la sequenza ordinata, Classi ed attributi: Identi chiamo due classi di algoritmi di ordinamento X [i ] ≤ X [ j ] • Confronti e scambi : le operazioni eseguite sui dati sono quelle di confronto, , e X [i ] := X [ j ]assegnamento, • Digitali : le operazioni possono riguardare singoli ( o gruppi di ) bit della rappresentazione di ciascun elemento DEFINIZIONE Un metodo di ordinamento si dice : • STABILE : se rispetta l’ordine relativo degli elementi di ugual valore • ADATTIVO : se i confronti e ettuati dipendono
dai dati
DEFINIZIONE [ Equivalenza per confronti ]
n ≈ ⊆ U × U X ≈ Y
Sia la relazione de nita da se e solo se
C C∀i, j X [i ] < X [ j ] ⇔ Y [i ] < Y [ j ]
X ≈ Y equivalenti per confronti
Due sequenze tali che si dicono
C⇒ ≈
FATTO è una relazione di equivalenza
CDEFINIZIONE [ Inversione ] n |X ∈ U (i, j ) i < j e X [i ] > X [ j ]
Un inversione in una sequenza è una coppian |X ∈ U N (X ) = #{(i, j ) (i, j ) e′ un inversione di X}
Il numero di inversioni di è invn(n − 1)n⇒ ∀X ∈ U 0 ≤ N (X ) ≤
FATTO inv 2N (X ) = 0 → X ordinata• inv n(n − 1)N (X ) = → X ordinata al contrario• inv 2
Limite inferiore al numero di confronti eseguiti nel caso peggiore per la classe “confronti escambi”
Lemma 1 ⌈ ⌉H(k) k H(k) ≥ log k
Sia l’altezza di un albero binario con foglie. Allora, 2
Teorema [ Lower bound per l’ordinamento
Qualunque algoritmo della classe "confronti e scambi" esegue nel caso peggiore almeno nlog n + o(nlog n) confronti per ordinare una sequenza di dati. Dimostrazione: Per il lemma 1 l'altezza dell'albero è maggiore o uguale a n⌈log n⌉⌈log n⌉∑log n! = log i = nlog n + o(nlog n) Metodi della classe "confronti e scambi": SELECTIONSORT ```java public class Selection{ public static void sort(Comparable[] a){ int N = a.length; for(int i=0; i
i<N; I++){
int j = i;
while(j>0 && less(a[j],a[j-1])){
exch(a,j,j-1);
j—;
}
}
- L'algoritmo è stabile
- L'algoritmo è adattivo
Complessità:
- Caso Migliore (Vettore Ordinato): n-1 ∑ 1 = n - 1 = Θ(n)
- Caso Peggiore (Vettore Ordinato al contrario): n-1 2n(n + 1) n 2∑ i = - 1 ≈ Θ(n^2)
- Caso Medio: 2n∑N. Confronti/Scambi : 4 2O(n)
Il numero complessivo di operazioni è in ogni caso 13 di 3218- Metodi Digitali
BUCKETSORT
public static void bucketsort(DEQueue<String> l){
String w;
DEQueue<String>[ ] s;
s= new DEQueue<String>[NSIMB];
for(int j=LENGTHWORD;j>0;j—){
while(!Is_empty(l)){
w=l.front();
l.delete(1);
e=Digit(w,j);
s[e].enqueue(w);
}
}
for(int i=1; i<NSIMB; i++){
s[0].chain(s[I]);
s[i]=null;
}
l=s[0];
s[0]=null;
}
- Il Bucketsort è stabile
- Non è possibile determinare la complessità senza ulteriori informazioni
adattivo Θ(k (n + m))
Ha complessità dove:
- k è la lunghezza delle parole
- m è la carnalità dell’alfabeto
- n è il numero di parole
19- MergingProblema [ Merging a due vie ]
V, W ∈ U*Input : due sequenze ordinate V, W
Output : una sequenza ordinata contenente tutti gli elementi diV, W ⇔
- merging di vettorirappresentate da vettoriV, W ⇔
- merging di listerappresentate da liste
Merging di Vettori : ComplessitàΘ(n + n )
Spazio : 1 2
Numero di confronti : Θ(n + n )
Caso Peggiore :
- 1 2Θ(1)
Caso Migliore :
Quando una delle due sequenze si esaurisce, si devono copiare tutti gli elementi rimanentiΘ(n + n ) in ogni caso.
nell’altro vettore. Quindi le operazioni eseguite sono 1 2
Merging di Liste : ComplessitàΘ(n + n )
Spazio : 1 2
Numero di confronti : Quando una delle due liste si esaurisce, il resto viene concatenato
inO(1)tempo , per questo motivo il tempo corrisponde al numero di confronti :Θ(n + n )
Caso Peggiore :• 1 2O(1)•
Caso Migliore :O(n + n )
Caso Medio :• 1 2 14 di 3220
- Divide et Impera
Una tecnica di progettazione di algoritmi che spesso porta alla soluzione e ciente di problemi
• Divide : spezza il problema in sottoproblemi di ugual dimensione
• Impera : risolvi ricorsivamente i sottoproblemi e unisci le soluzioni parziali a formare la soluzionedel problema di partenza
Equazione Divide et Impera
La complessità di un algoritmo divide et impera viene descritta da un’equazione di ricorrenza notanT (n) = mT ( ) + f (n)