La tua soluzione è valida e segue la definizione di heap d -ary. Ma come hai sottolineato la tua notazione è un po 'sofisticata.
È possibile utilizzare le due seguenti funzioni per recuperare parent of i -th element e j -th child of i -th element.
d-ary-parent(i) return ⌊(i−2)/d+1⌋
d-ary-child(i,j) return d(i−1)+j+1
Ovviamente . Puoi verificare quelle funzioni controllando che1≤j≤dd-ary-parent(d-ary-child(i,j))=i
È anche facile vedere che l'heap binario è un tipo speciale di heap -ary dove , se sostituisci con , vedrai che corrispondono alle funzioni PARENT, LEFT e RIGHT menzionate nel libro.dd=2d2
Se capisco correttamente la tua risposta, usi una progressione geometrica . Nel tuo caso vai go , che è ovviamente , che in realtà è una soluzione valida e corretta. Ma solo per gestire fluttuazioni costanti potresti voler scrivere .h=logd(nd−1+1)−1logd(nd)−1=logd(n)+logd(d)−1=logd(n)+1−1=logd(n)Θ(logd(n))
La ragione di ciò è che alcuni cumuli potrebbero non essere bilanciati, quindi il loro percorso più lungo e il percorso più breve possono variare di qualche costante , usando la notazione si elimina questo problema.cΘ
Non è necessario implementare nuovamente la procedura fornita nel libro di testo, ma è necessario modificarla un po ', ad es. Assegnando tutti i bambini alla tabella usando e funzioni.AUXd-ary-parentd-ary-child
Poiché non è stato modificato, dipende dal tempo di esecuzione di . Nella tua analisi ora devi usare il tempo peggiore proporzionale all'altezza e al numero di bambini che ciascun nodo deve esaminare (che è al massimo d ). Ancora una volta la tua analisi è molto precisa, alla fine hai ottenuto , che può essere trasformato in:EXTRACT-MAXMAX-HEAPIFYO(d logd(n(d−1)))
O(d logd(n(d−1)))=O(d(logd(n)+log(d−1)))=O(d logd(n)+d logd(d−1))
Per motivi pratici possiamo sempre presumere che , quindi possiamo perdere la parte della notazione O , quindi otterremo . Qual è anche una soluzione valida. Ma non sorprende che tu possa anche analizzare il tempo di esecuzione della funzione usando il teorema del Maestro , che mostrerà che non è solo ma anche .d≪ndlogd(d−1)O(dlogd(n))MAX-HEAPIFYOΘ
Il libro CLRS fornisce già la procedura INSERT. Che assomiglia a questo:
INSERT(A,key) A.heap_size=A.heap_size+1 A[A.heap_size]=−∞ INCREASE-KEY(A,A.heap_size,key)
Può essere facilmente provato, ma il buon senso impone che la sua complessità temporale sia . È perché l'heap potrebbe essere attraversato fino alla radice.O(logd(n))
Proprio come INSERT, INCREASE-KEY è anche definito nel libro di testo come:
INCREASE-KEY(A,i,key) if key<A[i] error"new key is smaller then current" A[i]=key while i>1 and A[i]>A[d-ary-parent(i)] A[i]↔A[d-ary-parent(i)] i=d-ary-parent(i)
La complessità è ovviamente (vedi punto precedente).O(logd(n))
h = (log [nd−1+1])− 1Pertanto la spiegazione sopra l'altezza non sarà valida. h = log [nd − 1 + 1] −1 = log [nd] -1 = log [n] Sebbene comunque, l'altezza dell'albero è scritta comeΘ(log(n)).Nota: il log è sempre alla base d per un heap d-ary .