2009-11-24 16 views

risposta

-4

Non credo. Penso che il meglio che puoi fare sia O (log n) o un po 'meglio con qualcosa come un ammasso di fibrosi.

+3

'O (log n)' è 'O (n)' (cioè, se 'f' è' O (log n) 'poi' f' se 'O (n)'). – jason

+0

Penso che abbia voluto dire O (n log n)? – PeterAllenWebb

+0

Non è chiaro per me. Penso che gli inserti in un heap di Fibonacci vengano ammortizzati 'O (1)' e quindi la costruzione viene ammortizzata 'O (n)'. – jason

0

Suggerimento: supponiamo che al posto di un array sia stato assegnato un albero binario arbitrario. Riesci a pensare a un modo efficace per correggere tutti i nodi che non soddisfano la proprietà heap?

-1

Se si utilizza uno Fibonacci Heap si ottiene amortized O (1) inserimento. Di conseguenza, è possibile creare un heap massimo in O (n) ammortizzato da un array.

L'attuazione di tale, lascio come esercizio *.

* Tuttavia, ci sono implementazioni di esempio collegate sulla pagina di Wikipedia.

5

Sì, c'è: Building a heap.

+0

+1. Altro per il tono della risposta rispetto alla risposta stessa :) – Anna

+1

Il tuo link suggerisce che non è possibile. Avrebbe dovuto dire di no non c'è ... – PeterAllenWebb

+0

@Peter: citazione dal link: "Pertanto, il costo di heapificare tutti i sottoalberi è: [snip equations] O (n)" –

22

Sì, come in questo codice:

for (int i = N/2; i >= 0; --i) 
    push_heap(heap + i, N - i); 

(push_heap è una funzione che accetta un puntatore ad un cumulo e la dimensione heap e spinge la parte superiore del mucchio finché le condizioni mucchio siano rispettate o il nodo raggiunge il fondo del mucchio).

Per ottenere il motivo per cui questo è O (N) guardare l'albero binario completo:

  • 1/2 elementi (ultimo livello, i> N/2) sono spinti verso il basso al massimo 0 punti -> N/2 * 0 operazioni
  • 1/4 elementi (ultimo livello 1, i> N/4) vengono premuti al massimo 1 passo -> N/4 * 1 operazioni
  • 1/8 elementi (ultimo- 2 livelli, i> N/8) sono premuti al massimo 2 passi -> N/8 * 2 operazioni ...

    N/4 * 1 + N/8 * 2 + N/16 * 3 + ... = 
    
        N/4 * 1 + N/8 * 1 + N/16 * 1 + ... + 
          N/8 * 1 + N/16 * 2 + ... = 
    
        N/4 * 1 + N/8 * 1 + N/16 * 1 + ... + // < N/2 
          N/8 * 1 + N/16 * 1 + ... + // < N/4 
             N/16 * 1 + ... + // < N/8 
               ... = // N/2 + N/4 + N/8 + ... < N 
    

Spero che la matematica non sia davvero troppo complicata. Se guardi sull'albero e aggiungi quanto può essere spinto verso il basso ciascun nodo, vedrai il limite superiore O (N).

+0

+1 per essere meno pigro di me :) –

+0

Uomo, hai reso la matematica molto più semplice dell'articolo WIKI! Grazie mille! – khelll

+0

Cosa per questo input: 1, 2, 3, 4, 5, 6, 7, 8, 9. Penso che dovrebbe essere O (nlogn)? –

Problemi correlati