Un problema di heap d-ary da CLRS


10

Mi sono confuso mentre risolvo il seguente problema (domande 1–3).

Domanda

Un heap d -ary è come un heap binario, ma (con una possibile eccezione) i nodi non foglia hanno d figli invece di 2 figli.

  1. Come rappresenteresti un heap d -ary in un array?

  2. Qual è l'altezza di un heap d -ary di n elementi in termini di n e d ?

  3. Fornire un'implementazione efficiente di EXTRACT-MAX in un d -ary max-heap. Analizzare il suo tempo di esecuzione in termini di d e n .

  4. Fornire un'implementazione efficiente di INSERT in un max-heap d -ary. Analizzare il suo tempo di esecuzione in termini di d e n .

  5. Fornire un'implementazione efficiente di INCREASE-KEY ( A , i , k ), che contrassegna un errore se k <A [i] = k e quindi aggiorna la struttura heap della matrice d -ary in modo appropriato. Analizzare il suo tempo di esecuzione in termini di d e n .

La mia soluzione

  1. Assegna un arrayA[a1..an]

    root:a1level 1:a2a2+d1level 2:a2+da2+d+d21level k:a2+i=1k1dia2+i=1kdi1

    → La mia notazione sembra un po 'sofisticata. Ce n'è un altro più semplice?

  2. Let h indica l'altezza dell'heap d -ary.

    Supponiamo che l'heap sia un albero d -ary completo

    1+d+d2+..+dh=ndh+11d1=nh=logd[nd1+1]1
  3. Questa è la mia implementazione:

    EXTRACT-MAX(A)
    1  if A.heapsize < 1
    2      error "heap underflow"
    3  max = A[1]
    4  A[1] = A[A.heapsize]
    5  A.heap-size = A.heap-size - 1
    6  MAX-HEAPIFY(A, 1)
    7  return max
    
    MAX-HEAPIFY(A, i)
    1  assign depthk-children to AUX[1..d]
    2  for k=1 to d
    3      compare A[i] with AUX[k]
    4      if A[i] <= AUX[k]
    5          exchange A[i] with AUX[k]
    6          k = largest
    7  assign AUX[1..d] back to A[depthk-children]
    8  if largest != i
    9      MAX-HEAPIFY(A, (2+(1+d+d^2+..+d^{k-1})+(largest-1) )
    
    • Il tempo di esecuzione di MAX-HEAPIFY:

      TM=d(c8d+(c9+..+c13)d+c14d)
      dove denota il costo dei -esimo linea sopra.ci
    • EXTRACT-MAX:

      TE=(c1+..+c7)+TMCdh=Cd(logd[n(d1)+1]1)=O(dlogd[n(d1)])

    È una soluzione efficiente? O c'è qualcosa di sbagliato nella mia soluzione?


Penso che ci sia un piccolo errore nella domanda e nella spiegazione: L'altezza dell'heap d-ary arriva a h = (log [nd - n + 1]) - 1 // NOTA è "-n" e non "-1" e non 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 .
Surabhi Raje,

Risposte:


10
  1. 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 (i2)/d+1

    d-ary-child(i,j)    return d(i1)+j+1

    Ovviamente . Puoi verificare quelle funzioni controllando che1jdd-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

  2. 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(nd1+1)1logd(nd)1=logd(n)+logd(d)1=logd(n)+11=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Θ

  3. 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(d1)))

    O(d logd(n(d1)))=O(d(logd(n)+log(d1)))=O(d logd(n)+d logd(d1))

    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 .dndlogd(d1)O(dlogd(n))MAX-HEAPIFYOΘ

  4. 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))

  5. 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))


Grazie! Che ne dici dell'implementazione di INCREASE-KEY e INSERT? Provo a scriverlo, ma mi ha dato due volte ricorsive di MAX-HEAPIFY. C'è una soluzione migliore? Ho trovato poche informazioni su web e wiki
lucasKo

È quel resto dell'esercizio? In tal caso, aggiorna la tua domanda e sarò felice di rispondere al tema.
Bartosz Przybylski,

Ho posto quelle domande sul post modificato.
lucasKo

reimplementare la procedura INSERT? Vuoi dire, non deve chiamare la procedura che regola l'ordine all'interno dell'heap, dopo aver inserito un nuovo elemento? Non capisco ...
lucasKo

Quella descrizione è stata un po 'sfortunata, vedi le modifiche per la clearificazione.
Bartosz Przybylski,

1

Questa non è una risposta completa. parte b) la soluzione non è Its come sottolineato dall'utente 55463 (perché non può commentare, ma rispondere), ma ha effettuato il downgrade per mancanza di spiegazioni . Anche la risposta votata ha risolto per errore. La risposta sarà ancora Fonte: Problema 2-2. Analisi di cumuli di dary, parte b)

h=logd[nd1+1]1
h = Θ ( log d ( n ) )
1+d+d2+..+dh=ndh+11d1=nh=logd[n(d1)+1]1
h=Θ(logd(n))

-1

La risposta alla seconda domanda è h = log d (n (d-1) + 1) - 1 Quindi, h = log d (nd - n + 1) - 1


4
Perché questa è la risposta? Una formula senza spiegazione non aiuta davvero nessuno.
David Richerby,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.