La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Algoritmi e Strutture Dati HeapSort. Select Sort: intuizioni L’algoritmo Select-Sort  scandisce tutti gli elementi dell’array a partire dall’ultimo elemento.

Presentazioni simili


Presentazione sul tema: "Algoritmi e Strutture Dati HeapSort. Select Sort: intuizioni L’algoritmo Select-Sort  scandisce tutti gli elementi dell’array a partire dall’ultimo elemento."— Transcript della presentazione:

1 Algoritmi e Strutture Dati HeapSort

2 Select Sort: intuizioni L’algoritmo Select-Sort  scandisce tutti gli elementi dell’array a partire dall’ultimo elemento fino all’inizio e ad ogni iterazione:  Viene cercato l’elemento massimo nella parte di array precedente l’elemento corrente  l’elemento massimo viene scambiato con l’elemento corrente n 1 max ordinati disordinati i

3 Select Sort Select-Sort(A) FOR i = length[A] DOWNTO 2 DO max = Findmax(A,i) “scambia A[max] e A[i]” Findmax(A,x) max = 1 FOR i = 2 to x DO IF A[max] < A[i] THEN max = i return max

4 Heap Sort L’algoritmo Heap-Sort :  è una variazione di Select-sort in cui la ricerca dell’elemento massimo è facilitata dall’utilizzo di una opportuna struttura dati  la struttura dati è chiamata heap  lo heap è una variante della struttura dati albero binario  in uno heap l’elemento massimo può essere acceduto in tempo costante.

5 Alberi binari Un albero binario è una struttura dati astratta definita come un insieme finito di nodi che  è vuoto oppure  è composto da tre insiemi disgiunti di nodi:  un nodo radice  un albero binario detto sottoalbero sinistro  un albero binario detto sottoalbero destro

6 Alberi binari sottoalbero sinistro sottoalbero destro nodo radice

7 Alberi binari sottoalbero destro nodo radice sottoalbero destro Radice del sotto- albero sinistro sottoalbero sinistro

8 Alberi binari nodo radice sottoalbero destro sottoalbero sinistro sottoalbero destro Radice del sotto- albero sinistro Radice del sotto- albero destro sottoalbero sinistro

9 Alberi binari nodo radice sottoalbero sinistro sottoalbero destro

10 Alberi binari nodo radice nodo i nodo j nodo k figli del nodo i padre dei nodi j e k arco dal nodo i al nodo k

11 Alberi binari  In nodo di un albero binario si dice nodo foglia (o solo foglia) se non ha figli (cioè se entrambi i sottoalberi di cui è radice sono vuoti)  Un nodo si dice nodo interno se ha almeno un figlio  Un percorso dal nodo i al nodo j è la sequenza di archi che devono essere attraversati per raggiungere il nodo j dal nodo i

12 Alberi binari nodo radice nodi interni nodi foglia percorso dalla radice al nodo k nodo k

13 Alberi binari  In un albero binario la profondità di un nodo è la lunghezza del percorso dalla radice al nodo (cioè il numero di archi tra la radice e il nodo)  La profondità maggiore di un nodo all’interno di un albero è l’altezza dell’albero.  Il grado di un nodo è il numero di figli di quel nodo.

14 Alberi binari nodo radice Profondità 3 Profondità 2 Profondità 1 Profondità 0

15 Alberi binari nodo radice Profondità 3 Profondità 2 Profondità 1 Profondità 0 Altezza 3

16 Alberi binari nodo radice Profondità 2 Profondità 1 Profondità 0 Altezza 3 Grado 1 Grado 2 Profondità 3

17 Alberi binari completo Un albero binario si dice completo se  tutte le foglie hanno la stessa profondità h  tutti i nodi interni hanno grado 2  Un albero completo di n nodi ha altezza esattamente  log 2 n .  Un albero completo di altezza h ha esattamente 2 h+1 -1 nodi.

18 Alberi binari completo n = 15 e altezza h =  log 2 n  = 3 1 23 4 5 6 7 89 10 1112131415 n = 2 h +1 -1 = 2 4 -1 = 15

19 Alberi binari quasi completo Un albero binario si dice quasi completo se ¶ tutte le foglie hanno profondità h o h-1, dove h è l’altezza dell’albero · tutti i nodi interni hanno grado 2, eccetto al più uno.

20 Alberi binari quasi completo nodi foglia profondità h profondità h-1 profondità 0 nodo con un solo figlio

21 Condizioni 1 e 2 definiscono la forma dell’albero Proprietà di uno Heap Un Albero Heap è un albero binario tale che per ogni nodo i: ¶ tutte le foglie hanno profondità h o h-1, dove h è l’altezza dell’albero; · tutti i nodi interni hanno grado 2, eccetto al più uno; ¸ entrambi i nodi j e k figli di i sono NON maggiori di i.

22 Proprietà di uno Heap Un Albero Heap è un albero binario tale che per ogni nodo i: ¶ tutte le foglie hanno profondità h o h-1, dove h è l’altezza dell’albero; · tutti i nodi interni hanno grado 2, eccetto al più uno; ¸ entrambi i nodi j e k figli di i sono NON maggiori di i. Condizione 3 definisce l’etichettatura dell’albero

23 Proprietà di uno Heap Un Albero Heap è un albero binario quasi completo tale che per ogni nodo i: l entrambi i nodi j e k figli di i sono NON maggiori di i.

24 Heap 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 Heap NON impone alcuna relazione di ordinamento tra I figli di un nodo

25 Heap e Ordinamenti Parziali Un Albero Heap è un albero binario quasi completo tale che per ogni nodo i:  entrambi i nodi j e k figli di i sono NON maggiori di i. Uno Heap rappresenta un Ordiamento Parziale

26 Heap e Ordinamenti Parziali Un Ordinamento Parziale è una relazione tra elementi di un insieme che è:  Riflessiva: x è in relazione con se stesso  Anti-simmetrica: se x è in relazione con y e y è in relazione con x allora x = y  Transitiva: se x è in relazione con y e y è in relazione con z allora x è in relazione con z Esempi: le relazioni  e  le relazioni >, < NON sono ordinamenti parziali

27 Heap e Ordinamenti Parziali Gli Ordinamenti Parziali possono essere usati per modellare gerarchie con informazione incompleta o elementi con uguali valori L’ordinamento parziale definito da uno Heap è una nozione più debole di un ordinamento totale, infatti uno Heap  è più semplice da costruire  è molto utile ma meno dell’ordinamento totale

28 Implementazione di uno Heap Uno Heap può essere implementato in vari modi:  come un albero a puntatori  come un array  ….

29 Heap: da albero ad array 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 1 2 3 4 5 6 7 8 9 10 11 12 45 34 28 30 25 22 12 14 21 15 16 20

30 Heap: da albero ad array 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12 Uno Heap può essere implementato come un array A in cui:  la radice dello Heap sta nella posizione A[0] dell’array  se il nodo i dello Heap sta nella posizione A[i ] dell’array,  il figlio sinistro di i sta nella posizione A[2i ]  il figlio destro di i sta nella posizione A[2i +1]

31 Heap: da albero ad array 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12

32 Heap: da albero ad array 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12

33 Heap: da albero ad array 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12

34 Heap: da albero ad array 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12

35 Heap: da albero ad array 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12

36 Heap: da albero ad array 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12

37 Proprietà di uno Heap 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12 Un Albero Heap è un albero binario quasi completo tale che per ogni nodo i:  entrambi i nodi j e k figli di i sono NON maggiori di i. Un array A è uno Heap se A[i ]  A[2i ] e A[i]  A[2i+1]

38 Operazioni elementari su uno Heap SINISTRO(i) return 2i DESTRO(i) return 2i + 1 PADRE(i) return  i/2  heapsize[A]  n è la lunghezza dello Heap 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12

39 Operazioni su uno Heap  Heapify(A,i) : ripristina la proprietà di Heap al sottoalbero radicato in i assumendo che i suoi sottoalberi destro e sinistro siano già degli Heap  Costruisci-Heap(A) : produce uno Heap a partire dall’array A non ordinato  HeapSort(A) : ordina l’array A sul posto.

40 Heapify: Intuizioni Heapify(A,i) : dati due Heap H 1 e H 2 con radici SINISTRO(i) e DESTRO(i) e un nuovo elemento v in posizione A[i]  se lo Heap H con radice A[i]= v viola la proprietà di Heap allora:  metti in A[i] la più grande tra le radici degli Heap H1 e H2  applica Heapify ricorsivamente al sottoalbero selezionato (con radice A[2i] o A[2i+1] ) e all’elemento v (ora in posizione A[2i] o A[2i+1] ).

41 Algoritmo Heapify Heapify(A,i) l = SINISTRO (i) r = DESTRO(i) IF l  heapsize[A] AND A[l] > A[i] THEN maggiore = l ELSE maggiore = i IF r  heapsize[A] AND A[r] > A[maggiore] THEN maggiore = r IF maggiore  i THEN “scambia A[i] e A[maggiore]” Heapify(A,maggiore)

42 Heapify 45 14 2534 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i … IF l  heapsize[A] AND A[l] > A[i] THEN maggiore = l ELSE maggiore = i … lr

43 Heapify 45 14 2534 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i … IF l  heapsize[A] AND A[l] > A[i] THEN maggiore = l ELSE maggiore = i … maggiore lr

44 Heapify 45 14 2534 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i … IF r  heapsize[A] AND A[r] > A[maggiore] THEN maggiore = r … maggiore lr

45 Heapify 45 14 2534 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i … IF maggiore  i THEN “scambia A[i] e A[maggiore]” Heapify(A,maggiore) … maggiore lr

46 Heapify 45 34 2514 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i … IF maggiore  i THEN “scambia A[i] e A[maggiore]” Heapify(A,maggiore) … maggiore lr

47 Heapify 45 34 2514 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i … IF maggiore  i THEN “scambia A[i] e A[maggiore]” Heapify(A,maggiore) … maggiore lr

48 Heapify 45 34 2514 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i … IF maggiore  i THEN “scambia A[i] e A[maggiore]” Heapify(A,maggiore) … lr

49 Heapify 45 34 2514 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i lr … IF l  heapsize[A] AND A[l] > A[i] THEN maggiore = l ELSE maggiore = i …

50 Heapify 45 34 2514 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i lr … IF l  heapsize[A] AND A[l] > A[i] THEN maggiore = l ELSE maggiore = i … maggiore

51 Heapify 45 34 2514 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 i lr maggiore … IF r  heapsize[A] AND A[r] > A[maggiore] THEN maggiore = r …

52 Heapify 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 i lr maggiore … IF maggiore  i THEN “scambia A[i] e A[maggiore]” Heapify(A,maggiore) …

53 Heapify 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 i … IF maggiore  i THEN “scambia A[i] e A[maggiore]” Heapify(A,maggiore) …

54 Heapify 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 i … IF l  heapsize[A] AND A[l] > A[i] THEN maggiore = l ELSE maggiore = i IF r  heapsize[A] AND A[r] > A[maggiore] THEN maggiore = r … Entrambi i test sono falsi perché l e r sono maggiori di heapsize[A]

55 Heapify 45 34 2530 28 1222 2114161520 1 23 4 5 6 7 89 10 1112 i Heapify termina! È stata ripristi- nata la proprietà Heap

56 Heapify(A,i) l = SINISTRO(i) r = DESTRO(i) IF l  heapsize[A] AND A[l] > A[i] THEN maggiore = l ELSE maggiore = i IF r  heapsize[A] AND A[r] > A[maggiore] THEN maggiore = r IF maggiore  i THEN “scambia A[i] e A[maggiore]” Heapify(A,maggiore) Complessità di Heapify T(n) = max(O(1),max(O(1),T(?) + O(1))

57 Complessità di Heapify:caso peggiore T(n) = max(O(1),max(O(1),T(?) + O(1)) Nel caso peggiore Heapify ad ogni chiamata ricorsiva, viene eseguito su un numero di nodi che è minore dei 2/3 del numero di nodi correnti n. Cioè il numero di nodi n s del sottoalbero su cui Heapify è chiamato ricorsivamente è al più 2/3 n (o n s  2/3 n )

58 Complessità di Heapify:caso peggiore 45 34 2530 28 1222 21141615 1 23 4 5 6 7 89 10 11 nsns nrnr n s /n ha valore massimo

59 Complessità di Heapify:caso peggiore 45 34 2530 28 1222 211415 1 23 4 5 6 7 89 10 nsns nrnr n s /n è minore del massimo (n s è più piccolo)

60 Complessità di Heapify:caso peggiore 45 34 2530 28 1222 21141615 1 23 4 5 6 7 89 10 11 20 12 nsns nrnr n s /n è minore del massimo (n è più grande)

61 Complessità di Heapify:caso peggiore 45 34 2530 28 1222 21141615 1 23 4 5 6 7 89 10 11 Albero completo di altezza h-1 Albero completo di altezza h-2 n = 1 + 2 h -1 + 2 h-1 -1 = 3 2 h-1 - 1 Numero di nodi n r =2 h-1 -1 Numero di nodi n s =2 h -1 nsns nrnr

62 Complessità di Heapify:caso peggiore 45 34 2530 28 1222 21141615 1 23 4 5 6 7 89 10 11 Albero completo di altezza h-1 Numero di nodi n r =2 h-1 -1 Numero di nodi n s =2 h -1 n s /n = 2 h -1/(3 2 h-1 -1)  2/3 Albero completo di altezza h-2 nsns nrnr

63 Complessità di Heapify:caso peggiore T(n) = max(O(1),max(O(1),T(?) + O(1))  max(O(1),max(O(1),T(2n/ 3) + O(1))  T(2n/ 3) +  (1) T’(n) = T’(2n/ 3) +  (1) Proviamo ad applicare il Metodo Iterativo! T’(n) =  (log n)

64 Complessità di Heapify:caso peggiore T(n) = max(O(1),max(O(1),T(?) + O(1))  max(O(1),max(O(1),T(2n/ 3) + O(1))  T(2n/ 3) +  (1) Quindi T(n) = O (log n) Heapify impiega tempo proporzionale all’altezza dell’albero su cui opera !

65 Complessità di Heapify:caso migliore T(n) = T(?) + O(1) Nel caso migliore Heapify ad ogni chiamata ricorsiva, viene eseguito su un numero di nodi che è maggiore di 1/3 del numero di nodi correnti n. Cioè il numero di nodi n s del sottoalbero su cui Heapify è chiamato ricorsivamente è al più 1/3 n (o n s  1/3 n )

66 Complessità di Heapify:caso migliore T(n) = T(?) + O(1)  T(n/ 3) +  (1) T’(n) = T’(n/ 3) +  (1) Applicando il Metodo Iterativo! T’(n) =  (log n) quindi T(n) =  (log n)

67 Costruisci Heap: intuizioni Costruisci-Heap(A) : utilizza l’algoritmo Heapify, per inserire ogni elemento dell’array in uno Heap, risistemando sul posto gli elementi:  gli ultimi  n/2  elementi dell’array sono foglie, cioè radici di sottoalberi vuoti, quindi sono già degli Heap  è sufficiente inserire nello Heap solo i primi  n/2  elementi, utilizzando Heapify per ripristi- nare la proprietà Heap sul sottoalbero del nuovo elemento.

68 Costruisci Heap Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i)

69 Costruisci Heap 14 45 1534 28 1220 2130162522 1 23 4 5 6 7 89 10 1112 14 45 28 34 15 20 12 30 21 25 16 22 1 2 3 4 5 6 7 8 9 10 11 12

70 Costruisci Heap 14 45 1534 28 1220 2130162522 1 23 4 5 6 7 89 10 1112 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) i = 6i = 6

71 Costruisci Heap 14 45 1534 28 1220 2130162522 1 23 4 5 6 7 89 10 1112 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) i = 6i = 6

72 Costruisci Heap 14 45 1534 28 1222 2130162520 1 23 4 5 6 7 89 10 1112 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) i = 6i = 6 Heap

73 Costruisci Heap 14 45 1534 28 1222 2130162520 1 23 4 5 6 7 89 10 1112 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) i = 5i = 5

74 Costruisci Heap 14 45 2534 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) i = 5i = 5 Heap

75 Costruisci Heap 14 45 2534 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) i = 4i = 4

76 Costruisci Heap 14 45 2534 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) i = 4i = 4 Heap

77 Costruisci Heap 14 45 2534 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) i = 3i = 3 Heap

78 Costruisci Heap 14 45 2534 28 1222 2130161520 1 23 4 5 6 7 89 10 1112 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) i = 2i = 2 Heap

79 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) Costruisci Heap 45 2534 28 1222 2130161520 23 4 5 6 7 89 10 1112 i = 1i = 1 14 1

80 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) Costruisci Heap 45 2534 28 1222 2130161520 23 4 5 6 7 89 10 1112 i = 1i = 1 14 1

81 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) Costruisci Heap 14 2534 28 1222 2130161520 23 4 5 6 7 89 10 1112 i = 1i = 1 1 45

82 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) Costruisci Heap 34 2514 28 1222 2130161520 23 4 5 6 7 89 10 1112 i = 1i = 1 1 45

83 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) Costruisci Heap 34 2530 28 1222 2114161520 23 4 5 6 7 89 10 1112 i = 1i = 1 1 45

84 Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i) Costruisci Heap 34 2530 28 1222 2114161520 23 4 5 6 7 89 10 1112 i = 1i = 1 1 45 Heap

85 Costruisci Heap 34 2530 28 1222 2114161520 23 4 5 6 7 89 10 1112 1 45 Heap 45 34 28 30 25 22 12 14 21 15 16 20 1 2 3 4 5 6 7 8 9 10 11 12

86 Complessità di Costruisci Heap Costruisci-Heap(A) heapsize[A] = length[A] FOR i =  length[A]/2  DOWNTO 1 DO Heapify(A,i)

87 Complessità di Costruisci Heap T(n) = max(O(1), O(?)) = max(O(1), O(f(n))) Poiché Heapify viene chiamata n/2 volte si potrebbe ipotizzare f(n) = O(n log n) e quindi T(n) = max(O(1), O(n log n)) = O(n log n) ma….

88 Complessità di Costruisci Heap Costruisci-Heap chiama Heapify n/2 volte su Heap di altezza 0 (non eseguito) n/4 volte su Heap di altezza 1 n/8 volte su Heap di altezza 2 … n/2 h+1 volte su Heap di altezza h 14 45 1534 28 1220 2130162522 1 23 4 5 6 7 89 10 1112

89 Complessità di Costruisci Heap T(n) = max(O(1), O(?)) = max(O(1), O(f(n))) Costruisci-Heap chiama Heapify n/2 volte su Heap di altezza 0 (in reltà non eseguito) n/4 volte su Heap di altezza 1 n/8 volte su Heap di altezza 2 … n/2 h+1 volte su Heap di altezza h

90 Complessità di Costruisci Heap T(n) = max(O(1), O(?)) = max(O(1), O(f(n)))

91 Complessità di Costruisci Heap T(n) = max(O(1), O(?)) = max(O(1), O(f(n)))

92 Complessità di Costruisci Heap T(n) = max(O(1), O(?)) = max(O(1), O(f(n))) x = 1/2  1

93 Complessità di Costruisci Heap T(n) = max(O(1), O(?)) = max(O(1), O(f(n)))

94 Complessità di Costruisci Heap T(n) = max(O(1), O(?)) = max(O(1), O(f(n))) T(n) = max(O(1), O(n)) = O(n) Costruire uno Heap di n elementi è poco costoso, al più costa O(n) !

95 Heap Sort: intuizioni Heap-Sort : è una variazione di Select-sort in cui la ricerca dell’elemento massimo è facilitata dal mantenimento della sequenza in uno heap:  si costruisce uno Heap a partire dall’array non ordinato in input.  viene sfruttata la proprietà degli Heap per cui la radice A[1] dello Heap è sempre il massimo:  scandisce tutti gli elementi dell’array a partire dall’ultimo e ad ogni iterazione  la radice A[1] viene scambiata con l’elemento nell’ultima posizione corrente dello Heap  viene ridotta la dimensione dello Heap e  ripristinato lo Heap con Heapify

96 Heap Sort: intuizioni n 1 disordinati parzialmente ordinati heap n 1 costruisci heap max scambio + heapify n 1 max ordinati parzialmente ordinati heap i

97 Heap Sort Heap-Sort(A) Costruisci-Heap(A) FOR i = length[A] DOWNTO 2 DO /* elemento massimo in A[1] */ “scambia A[1] e A[i]” /* ripristina lo heap */ heapsize[A] = heapsize[A]-1 Heapify(A,1) Select-Sort(A) FOR i = length[A] DOWNTO 2 DO max = Findmax(A,i) “scambia A[max] e A[i]”

98 Heap Sort Heap-Sort(A) Costruisci-Heap(A) … 14 45 1534 28 1220 2130162522 1 23 4 5 6 7 89 10 1112

99 Heap Sort Heap-Sort(A) Costruisci-Heap(A) … 34 2530 28 1222 2114161520 23 4 5 6 7 89 10 1112 1 45

100 Heap Sort 34 2530 28 1222 2114161520 23 4 5 6 7 89 10 1112 1 45 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 12 heapsize[A]=12

101 Heap Sort 34 2530 28 1222 2114161545 23 4 5 6 7 89 10 1112 1 20 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 12 heapsize[A]=12

102 Heap Sort 34 2530 28 1222 21141615 23 4 5 6 7 89 10 11 1 20 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 12 45 12 heapsize[A]=11

103 Heap Sort 34 2530 28 1222 21141615 23 4 5 6 7 89 10 11 1 20 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 12 45 12 heapsize[A]=11

104 Heap Sort 30 2521 28 1222 2014161545 23 4 5 6 7 89 10 1112 1 34 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 12 heapsize[A]=11

105 Heap Sort 30 2521 28 1222 2014 16 15 45 23 4 5 6 7 89 10 1112 1 34 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 11 heapsize[A]=11

106 Heap Sort 30 2521 28 1222 201415 45 23 4 5 6 7 89 10 12 1 16 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 11 34 11 heapsize[A]=10

107 Heap Sort 25 1621 28 1222 2014 34 15 45 23 4 5 6 7 89 10 1112 1 30 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 11 heapsize[A]=10

108 Heap Sort 25 1621 28 1222 201415 23 4 5 6 7 89 10 1 30 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 10 3445 1112 heapsize[A]=10

109 Heap Sort 25 1621 28 1222 2014 23 4 5 6 7 89 1 15 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 10 3445 1112 heapsize[A]=9 30 10

110 Heap Sort 25 1621 22 1215 201430 23 4 5 6 7 89 10 1 28 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 10 3445 1112 heapsize[A]=9

111 Heap Sort 25 1621 22 1215 2014 23 4 5 6 7 89 1 28 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 9i = 9 30 10 3445 1112 heapsize[A]=9

112 Heap Sort 25 1621 22 1215 14 23 4 5 6 7 8 1 20 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 9i = 9 30 10 3445 1112 heapsize[A]=8 28 9

113 Heap Sort 21 1620 22 1215 2814 23 4 5 6 7 89 1 25 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 9i = 9 30 10 3445 1112 heapsize[A]=8

114 Heap Sort 21 1620 22 1215 14 23 4 5 6 7 8 1 25 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 8i = 8 28 9 30 10 3445 1112 heapsize[A]=8

115 Heap Sort 21 1620 15 1214 25 23 4 5 6 7 8 1 22 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 8i = 8 28 9 30 10 3445 1112 heapsize[A]=7

116 Heap Sort 21 1620 15 1214 23 4 5 6 7 1 22 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 7i = 7 25 8 28 9 30 10 3445 1112 heapsize[A]=7

117 Heap Sort 20 1612 15 22 14 23 4 5 6 7 1 21 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 7i = 7 25 8 28 9 30 10 3445 1112 heapsize[A]=6

118 Heap Sort 20 1612 15 22 14 23 4 5 6 7 1 21 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 6i = 6 25 8 28 9 30 10 3445 1112 heapsize[A]=6

119 Heap Sort 16 1412 15 2221 23 4 5 6 7 1 20 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 6i = 6 25 8 28 9 30 10 3445 1112 heapsize[A]=5

120 Heap Sort 16 1412 15 2221 23 4 5 6 7 1 20 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 5i = 5 25 8 28 9 30 10 3445 1112 heapsize[A]=5

121 Heap Sort 14 20 12 15 2221 23 4 5 6 7 1 16 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 5i = 5 25 8 28 9 30 10 3445 1112 heapsize[A]=4

122 Heap Sort 14 20 12 15 2221 23 4 5 6 7 1 16 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 4i = 4 25 8 28 9 30 10 3445 1112 heapsize[A]=4

123 Heap Sort 14 2016 12 2221 23 4 5 6 7 1 15 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 4i = 4 25 8 28 9 30 10 3445 1112 heapsize[A]=3

124 Heap Sort 14 2016 12 2221 23 4 5 6 7 1 15 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 3i = 3 25 8 28 9 30 10 3445 1112 heapsize[A]=3

125 Heap Sort 12 2016 152221 2 34 5 6 7 1 14 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 3i = 3 25 8 28 9 30 10 3445 1112 heapsize[A]=2

126 Heap Sort 12 2016 152221 2 34 5 6 7 1 14 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 2i = 2 25 8 28 9 30 10 3445 1112 heapsize[A]=2

127 Heap Sort 142016 152221 234 5 6 7 1 12 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 2i = 2 25 8 28 9 30 10 3445 1112 heapsize[A]=1

128 Heap Sort 142016 152221 234 5 6 7 1 12 Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 1i = 1 25 8 28 9 30 10 3445 1112 heapsize[A]=1

129 Heap Sort Heap-Sort(A) … FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1) i = 1i = 1 heapsize[A]=1 12 14 15 16 20 21 22 25 28 30 34 45 1 2 3 4 5 6 7 8 9 10 11 12 L’array A ora è ordinato!

130 Heap Sort Heap-Sort(A) Costruisci-Heap(A) FOR i = length[A] DOWNTO 2 DO “scambia A[1] e A[i]” heapsize[A] = heapsize[A]-1 Heapify(A,1)

131 Complessità di Heap Sort Nel caso peggiore Heap-Sort chiama una volta Costruisci-Heap; n-1 volte Heapify sullo Heap corrente T(n) = max(O(n), (n-1)  max(O(1), T(Heapify)))

132 Complessità di Heap Sort Nel caso peggiore Heap-Sort chiama una volta Costruisci-Heap; n-1 volte Heapify sull’intero Heap. T(n) = max(O(n), (n-1)  max(O(1), T(Heapify))) = max(O(n), max(O(n), O(n log n))) T(n) = O(n log n)

133 HeapSort: conlusioni HeapSort Algoritmo di ordinamento sul posto per confronto che impiega tempo O(n log n). Algoritmo non immediato nè ovvio. Sfrutta le proprietà della struttura dati astratta Heap.

134 HeapSort: conlusioni HeapSort dimostra che: scegliere una buona rappresentazione per i dati spesso facilita la progettazione di buoni algoritmi; importante pensare a quale può essere una buona rappresentazione dei dati prima di implementare una soluzione.


Scaricare ppt "Algoritmi e Strutture Dati HeapSort. Select Sort: intuizioni L’algoritmo Select-Sort  scandisce tutti gli elementi dell’array a partire dall’ultimo elemento."

Presentazioni simili


Annunci Google