In questo tutorial imparerai come funziona l'ordinamento della shell. Inoltre, troverai esempi funzionanti di ordinamento shell in C, C ++, Java e Python.
L'ordinamento della shell è un algoritmo che prima ordina gli elementi molto distanti l'uno dall'altro e successivamente riduce l'intervallo tra gli elementi da ordinare. È una versione generalizzata dell'ordinamento per inserzione.
Nell'ordinamento della shell, vengono ordinati gli elementi a un intervallo specifico. L'intervallo tra gli elementi viene gradualmente ridotto in base alla sequenza utilizzata. Le prestazioni dell'ordinamento della shell dipendono dal tipo di sequenza utilizzata per un dato array di input.
Alcune delle sequenze ottimali utilizzate sono:
- Sequenza originale di Shell:
N/2 , N/4 ,… , 1
- Gli incrementi di Knuth:
1, 4, 13,… , (3k - 1) / 2
- Gli incrementi di Sedgewick:
1, 8, 23, 77, 281, 1073, 4193, 16577… 4j+1+ 3·2j+ 1
- Gli incrementi di Hibbard:
1, 3, 7, 15, 31, 63, 127, 255, 511…
- Incremento di Papernov e Stasevich:
1, 3, 5, 9, 17, 33, 65,…
- Pratt:
1, 2, 3, 4, 6, 9, 8, 12, 18, 27, 16, 24, 36, 54, 81… .
Come funziona l'ordinamento della shell?
- Supponiamo di dover ordinare il seguente array.
Matrice iniziale
- Stiamo usando la sequenza originale della shell
(N/2, N/4,… 1
) come intervalli nel nostro algoritmo.
Nel primo ciclo, se la dimensione dell'array èN = 8
allora, gli elementi che si trovano nell'intervallo diN/2 = 4
vengono confrontati e scambiati se non sono in ordine.- Lo 0 ° elemento viene confrontato con il 4 ° elemento.
- Se lo 0 ° elemento è maggiore del 4 °, il 4 ° elemento viene prima memorizzato in
temp
variabile e l'0th
elemento (cioè l'elemento maggiore) viene memorizzato nella4th
posizione e l'elemento memorizzato intemp
viene memorizzato nella0th
posizione.Riorganizzare gli elementi con un intervallo n / 2
Questo processo continua per tutti gli elementi rimanenti.Riorganizza tutti gli elementi con un intervallo n / 2
- Nel secondo ciclo,
N/4 = 8/4 = 2
viene preso un intervallo di e di nuovo gli elementi che si trovano a questi intervalli vengono ordinati.Riorganizza gli elementi con un intervallo n / 4
A questo punto potresti confonderti.Vengono confrontati tutti gli elementi dell'array che si trovano nell'intervallo corrente.
Gli elementi in 4a e2nd
posizione vengono confrontati. Vengono confrontati anche gli elementi in seconda e0th
posizione. Vengono confrontati tutti gli elementi dell'array che si trovano nell'intervallo corrente. - Lo stesso processo va avanti per gli elementi rimanenti.
Riorganizza tutti gli elementi con un intervallo n / 4
- Infine, quando l'intervallo è,
N/8 = 8/8 =1
gli elementi dell'array che si trovano nell'intervallo 1 vengono ordinati. L'array è ora completamente ordinato.Riorganizza gli elementi con un intervallo n / 8
Algoritmo di ordinamento della shell
shellSort (array, size) per intervallo i <- size / 2n fino a 1 per ogni intervallo "i" nell'array ordina tutti gli elementi all'intervallo "i" end shellSort
Esempi di Python, Java e C / C ++
Python Java C C ++# Shell sort in python def shellSort(array, n): # Rearrange elements at each n/2, n/4, n/8,… intervals interval = n // 2 while interval> 0: for i in range(interval, n): temp = array(i) j = i while j>= interval and array(j - interval)> temp: array(j) = array(j - interval) j -= interval array(j) = temp interval //= 2 data = (9, 8, 3, 7, 5, 6, 4, 1) size = len(data) shellSort(data, size) print('Sorted Array in Ascending Order:') print(data)
// Shell sort in Java programming import java.util.Arrays; // Shell sort class ShellSort ( // Rearrange elements at each n/2, n/4, n/8,… intervals void shellSort(int array(), int n) ( for (int interval = n / 2; interval> 0; interval /= 2) ( for (int i = interval; i = interval && array(j - interval)> temp; j -= interval) ( array(j) = array(j - interval); ) array(j) = temp; ) ) ) // Driver code public static void main(String args()) ( int() data = ( 9, 8, 3, 7, 5, 6, 4, 1 ); int size = data.length; ShellSort ss = new ShellSort(); ss.shellSort(data, size); System.out.println("Sorted Array in Ascending Order: "); System.out.println(Arrays.toString(data)); ) )
// Shell Sort in C programming #include // Shell sort void shellSort(int array(), int n) ( // Rearrange elements at each n/2, n/4, n/8,… intervals for (int interval = n / 2; interval> 0; interval /= 2) ( for (int i = interval; i = interval && array(j - interval)> temp; j -= interval) ( array(j) = array(j - interval); ) array(j) = temp; ) ) ) // Print an array void printArray(int array(), int size) ( for (int i = 0; i < size; ++i) ( printf("%d ", array(i)); ) printf(""); ) // Driver code int main() ( int data() = (9, 8, 3, 7, 5, 6, 4, 1); int size = sizeof(data) / sizeof(data(0)); shellSort(data, size); printf("Sorted array: "); printArray(data, size); )
// Shell Sort in C++ programming #include using namespace std; // Shell sort void shellSort(int array(), int n) ( // Rearrange elements at each n/2, n/4, n/8,… intervals for (int interval = n / 2; interval> 0; interval /= 2) ( for (int i = interval; i = interval && array(j - interval)> temp; j -= interval) ( array(j) = array(j - interval); ) array(j) = temp; ) ) ) // Print an array void printArray(int array(), int size) ( int i; for (i = 0; i < size; i++) cout << array(i) << " "; cout << endl; ) // Driver code int main() ( int data() = (9, 8, 3, 7, 5, 6, 4, 1); int size = sizeof(data) / sizeof(data(0)); shellSort(data, size); cout << "Sorted array: "; printArray(data, size); )
Complessità
L'ordinamento della shell è un algoritmo di ordinamento instabile perché questo algoritmo non esamina gli elementi che si trovano tra gli intervalli.
Complessità temporale
- Complessità del caso peggiore : minore o uguale a La complessità del caso peggiore per l'ordinamento della shell è sempre minore o uguale a . Secondo Poonen Teorema, caso peggiore complessità per le coperture di tipo è o o o qualcosa tra.
O(n2)
O(n2)
Θ(Nlog N)2/(log log N)2)
Θ(Nlog N)2/log log N)
Θ(N(log N)2)
- Complessità caso migliore :
O(n*log n)
quando l'array è già ordinato, il numero totale di confronti per ogni intervallo (o incremento) è uguale alla dimensione dell'array. - Complessità media dei casi :
O(n*log n)
è intorno .O(n1.25)
La complessità dipende dall'intervallo scelto. Le complessità di cui sopra differiscono per le diverse sequenze di incremento scelte. La migliore sequenza di incremento è sconosciuta.
Complessità spaziale:
La complessità dello spazio per l'ordinamento della shell è O(1)
.
Applicazioni di ordinamento shell
L'ordinamento della shell viene utilizzato quando:
- chiamare uno stack è un sovraccarico. La libreria uClibc usa questo tipo.
- la ricorsione supera un limite. bzip2 compressor lo usa.
- L'ordinamento per inserzione non funziona bene quando gli elementi di chiusura sono molto distanti. L'ordinamento della shell aiuta a ridurre la distanza tra gli elementi vicini. Pertanto, il numero di scambi da eseguire sarà inferiore.