Se si desidera contare il numero di swap necessari nell'ordinamento per inserimento, si desidera trovare il seguente numero: per ciascun elemento, quanti elementi precedenti hanno l'array più piccolo di esso? La somma di questi valori è quindi il numero totale di scambi eseguiti.
Per trovare il numero, è possibile utilizzare un albero di statistica degli ordini, un albero di ricerca binario bilanciato in grado di indicare in modo efficiente quanti elementi dell'albero sono più piccoli di un dato elemento. Nello specifico, un albero delle statistiche di orde supporta l'inserimento di O (log n), la cancellazione, la ricerca e il conteggio del numero di elementi nella struttura ad albero inferiore a qualche valore. È quindi possibile contare quanti swap verranno eseguiti come segue:
- Inizializzare un nuovo albero di statistica di ordine vuoto.
- Set count = 0
- Per ogni elemento dell'array, in ordine:
- aggiungere l'elemento alla struttura statistica d'ordine.
- Aggiungi al conteggio il numero di elementi nell'albero inferiore al valore aggiunto.
- conteggio di ritorno,
Ciò O (n) iterazioni di un ciclo che prende O (log n), in modo che il lavoro totale fatto è O (n log n), che è più veloce rispetto all'approccio forza bruta.
Se si desidera contare il numero di scambi di ordinamento per selezione, allora si può utilizzare il fatto che l'inserimento sorta eseguirà solo swap del k-esimo passare se, dopo l'elaborazione dei primi k-1 elementi del lista, l'elemento in posizione k non è il k più piccolo elemento.Se si può fare questo in modo efficace, allora abbiamo il seguente schema di base di un algoritmo:
- insieme totale = 0
- Per k = 1 an:
- Se l'elemento in corrispondenza dell'indice k isn' t il quinto elemento più grande:
- Sostituirlo con il kesimo elemento più grande.
- Incremento totale
- rendimento totale
Quindi, come possiamo attuare in modo efficiente? Dobbiamo essere in grado di verificare in modo efficiente se l'elemento di un determinato indice è l'elemento corretto e anche di trovare in modo efficiente la posizione dell'elemento che effettivamente appartiene a un determinato indice altrimenti. Per fare ciò, iniziare creando un albero di ricerca binario bilanciato che mappa ciascun elemento nella sua posizione nell'array originale. Questo richiede tempo O (n log n). Ora che hai l'albero bilanciato, possiamo aumentare la struttura assegnando a ciascun elemento dell'albero la posizione nella sequenza ordinata a cui questo elemento appartiene. Un modo per farlo è con un albero di statistica degli ordini, e un altro dovrebbe essere iterare sull'albero con un attraversamento inorder, annotando ogni valore nell'albero con la sua posizione.
Utilizzando questa struttura, è possibile controllare O (log n) ora se un elemento è nella posizione corretta o meno guardando l'elemento nella struttura (tempo O (log n)), quindi guardando la posizione nella sequenza ordinata a cui dovrebbe essere e in quale posizione si trova attualmente (ricorda che lo abbiamo impostato durante la creazione dell'albero). Se non è d'accordo con la nostra posizione prevista, allora è nel posto sbagliato, e altrimenti è nel posto giusto. Inoltre, possiamo simulare in modo efficiente uno scambio di due elementi cercando quei due elementi nell'albero (tempo totale O (log n)) e poi scambiando le loro posizioni in O (1).
Come risultato, possiamo implementare l'algoritmo di cui sopra nel tempo O (n log n) - O (n log n) tempo per costruire l'albero, quindi n iterazioni di fare O (log n) funzionano per determinare se o non scambiare.
Spero che questo aiuti!
Scrivi la tua algoritmo di scambio, e tenere traccia del numero di swap. –
Perché la risposta 4? Puoi ordinarlo con 2 swap (scambia 'arr [0]' con 'arr [3]', e poi scambia 'arr [2]' con 'arr [4]'). –
O (n^2) è il numero di confronti sull'ordinamento di inserimento/selezione, non sugli scambi. –