Dal tuo commento, sembra che tu stia confondendo il significato di limiti inferiori, limiti superiori e notazione asintotica. Ad esempio, prendere Inserimento ordinamento. Il suo tempo di esecuzione nel migliore dei casi è (ciò accade quando l'input è già ordinato). Il suo tempo di esecuzione peggiore è (ciò accade quando l'ingresso è in ordine inverso). Quindi, poiché il tempo di esecuzione cade tra una funzione lineare di e una funzione quadratica di , puoi dire che il tempo di esecuzione di Insertion Sort è sia che . È importante capire in questo caso che non si può dire che il tempo di esecuzione èΘ ( n )Θ (n2)nnΩ ( n )O (n2)Ω (n2). Perché? Perché esiste un input che causa l'esecuzione dell'algoritmo in . Tuttavia, potresti dire che il tempo di esecuzione peggiore è , ancora una volta perché esiste un input che causa l'esecuzione dell'algoritmo in . Di solito usiamo la notazione nel caso peggiore, poiché siamo interessati a un limite superiore per il numero di operazioni eseguite dall'algoritmo.O ( n )Ω (n2)Ω (n2)O
Ora, pensiamo a un argomento avverso per Insertion Sort (potresti provare a ricavarne uno per Selection Sort applicando le stesse idee).
Considera l'algoritmo Insertion Sort che gioca contro un avversario che chiameremo avversario. Lo scopo dell'avversario è di fornire un input X per l'algoritmo che massimizzi il numero di confronti effettuati dall'algoritmo. Questo di solito viene analizzato nel contesto di alberi decisionali . Un albero decisionale mostra tutte le possibili sequenze di confronti che l'algoritmo potrebbe effettuare. Ogni nodo interno di un albero decisionale rappresenta un singolo confronto. I due figli di un nodo rappresentano i due risultati del confronto (sì / no o vero / falso). Ogni foglia rappresenta un possibile output. Per gli algoritmi di ordinamento, le foglie sono permutazionidelle chiavi. L'algoritmo inizia dalla radice e segue un percorso fino a una foglia. Ad ogni nodo interno, la risposta per il confronto fatto indica all'algoritmo quale nodo deve essere visitato successivamente. Quando l'algoritmo raggiunge una foglia, emette la sua permutazione corrispondente. Il tempo di esecuzione di un algoritmo (visto come un albero decisionale) per un dato input è il numero di confronti effettuati nel percorso dalla radice all'anta di output. Ora l'avversario ha una strategia semplice che funzionerà contro qualsiasi algoritmo di ordinamento basato sul confronto, incluso Insertion Sort: ogni volta che l'algoritmo fa un confronto, l'avversario sceglie la risposta che eliminerà il minor numero possibile di permutazioni.
In generale, a causa del fatto che con elementi ci sonopossibili permutazioni, qualsiasi albero decisionale per l'ordinamento deve avere almenolascia, e quindi deve avere profondità (per approssimazione di Stirling). Per Insertion Sort, l'avversario può creare un input particolare che fa sì che l'albero delle decisioni corrispondente abbia una profondità di almeno .nn !n !Ω ( log( n ! ) ) = Ω ( n logn )Ω (n2)
L'algoritmo utilizza un array per memorizzare gli elementi di input e si basa sul seguente invariante:A [ 1 . . n ]
All'inizio di ogni iterazione del ciclo for, il sottoarray costituito dagli elementi originariamente in , ma in ordine ordinato.A [ 1 . . j - 1 ]A [ 1 . . j - 1 ]
In ogni iterazione, gli elementi in sono quindi già in ordine, e l'algoritmo esamina e lo inserisce nella sua posizione corretta finale, confrontando il valore di con il valore degli elementi in , a partire da e procedendo nuovamente verso e così via fino a quando non è più il più grande nella confronto. Gli elementi in trovano in uno stato sconosciuto (per quanto riguarda l'ordinamento) e verranno elaborati in iterazioni successive.A [ 1 . . j - 1 ]A [ j ]A [ j ]A [ 1 . . j - 1 ]A [ j - 1 ]A [ j - 2 ]A [ j ]A [ j + 1 . . n ]
Ecco la strategia dell'avversario. Sapendo che l'algoritmo funziona inserendo al suo posto spostando gli elementi , allora la strategia ovvia è quello di massimizzare la -esima iterazione il numero di elementi che devono essere spostato per accogliere . Ciò si ottiene facilmente scegliendo attentamente l'input in modo che sia nell'ordine inverso . In effetti, in questo caso, il numero di elementi che devono essere spostati in ciascuna iterazione è . Ciò porta al tempo di esecuzione del caso peggiore (determinato dalla serie aritmetica corrispondente).A [ j ]A [ 1 . . j - 1 ]jA [ j ]j - 1Ω (n2)