Ordine rapida in Java ha spiegato

Ordine rapida in Java ha spiegato
Quick Ord, anche scritto come QuickSort, è uno schema di smistamento dell'elenco che utilizza il paradigma di divisione e conquista. Esistono diversi schemi per l'ordinamento rapido, tutti usando il paradigma di divisione e conquista. Prima di spiegare l'ordinamento rapido, il lettore deve conoscere la convenzione per dimezzare un elenco o un sotto-list e la mediana di tre valori.

Convenzione dimezzante

Quando il numero di elementi in un elenco è uniforme, dimezzare l'elenco significa che la prima metà letterale dell'elenco è la prima metà e la seconda metà letterale dell'elenco è la seconda metà. L'elemento medio (medio) dell'intero elenco, è l'ultimo elemento del primo elenco. Ciò significa che l'indice medio è lunghezza / 2 - 1, poiché il conteggio dell'indice inizia da zero. La lunghezza è il numero di elementi nell'elenco. Ad esempio, se il numero di elementi è 8, la prima metà dell'elenco ha 4 elementi e la seconda metà dell'elenco ha anche 4 elementi. Questo va bene. Poiché il conteggio dell'indice inizia da 0, l'indice centrale è 3 = 8 /2 - 1.

Che ne dici del caso, quando il numero di elementi nell'elenco o sotto l'elenco è dispari? All'inizio, la lunghezza è ancora divisa per 2. Per convenzione, il numero di elementi nella prima metà di questa divisione è la lunghezza / 2 + 1/2. Il conteggio dell'indice inizia da zero. L'indice medio è dato per lunghezza / 2 - 1/2. Questo è considerato il medio termine, per convenzione. Ad esempio, se il numero di elementi in un elenco è 5, allora l'indice centrale è 2 = 5/2 - 1/2. E ci sono tre elementi nella prima metà dell'elenco e due elementi nella seconda metà. L'elemento centrale dell'intero elenco è il terzo elemento all'indice, 2, che è l'indice medio perché il conteggio dell'indice inizia da 0.

La divisione in questo modo è un esempio di aritmetica intera.

Mediana di tre valori

Domanda: qual è la mediana della sequenza:

C b a

Soluzione:
Disporre l'elenco in ordine crescente:

A b c

Il medio termine, b, è la mediana. È la grandezza che si trova tra le altre due magnitudini.

Alla ricerca della mediana in un elenco non è quel tipo. Ad esempio, in un elenco di 19 elementi non portati, la mediana per il primo elemento, l'elemento medio e l'ultimo elemento potrebbero essere richiesti. Questi tre valori potrebbero non essere in ordine crescente; E così, i loro indici devono essere presi in considerazione.

Con un tipo rapido, la mediana per l'intero elenco e i sotto-listi sono richiesti. Lo pseudocode per cercare la mediana di tre valori distanziati in un elenco (array) è:

Mid: = ⌊ (basso + alto) / 2⌋
Se arr [Mid] < arr[low]
Swap arr [basso] con arr [mid]
Se arr [High] < arr[low]
SWAP ARR [basso] con arr [alto]
Se arr [Mid] < arr[high]
SWAP ARR [Mid] con arr [alto]
Pivot: = arr [High]

Il termine "arr" significa array. Questo segmento di codice cerca la mediana e fa anche qualche smistamento. Questo segmento di codice sembra semplice, ma può essere abbastanza confuso. Quindi, presta attenzione alla seguente spiegazione:

L'ordinamento in questo tutorial produrrà un elenco in cui il primo valore è il valore più piccolo e l'ultimo valore è il valore più grande. Con l'alfabeto, A è inferiore a z.

Qui, il perno è la mediana risultante. Basso è l'indice più basso dell'elenco o sotto-list (non necessariamente per il valore più basso); L'alto è l'indice più alto dell'elenco o della sotto-list (non necessariamente per il valore più alto) e il mezzo è l'indice centrale convenzionale (non necessariamente per il valore medio dell'intero elenco).

Quindi, la mediana da ottenere è tra il valore dell'indice più basso, il valore dell'indice medio e il valore dell'indice più alto.

Nel codice, l'indice centrale convenzionale si ottiene per primo. A questo inizio, l'elenco non è orientato. Il confronto e un po 'di riarrangiamento nell'ordine ascendente dei tre valori devono avvenire contemporaneamente. Il primo IF-Statement confronta il valore per l'indice più basso e quello dell'indice medio. Se quello dell'indice medio è inferiore a quello dell'indice più basso, le posizioni di scambio di due valori. Questo inizia l'ordinamento e modifica la disposizione dei valori nell'elenco o nell'elenco. Il secondo IF-Statement confronta il valore per l'indice più alto e quello dell'indice più basso. Se quello dell'indice più alto è inferiore a quello dell'indice più basso, le posizioni di scambio di due valori. Ciò comporta un po 'di ordinamento e modifica della disposizione dei valori nell'elenco o sottolinea. Il terzo IF-Statement confronta il valore per l'indice medio e quello dell'indice più alto. Se quello dell'indice più alto è inferiore all'indice medio, le posizioni di scambio di due valori. Qualche smistamento o riarrangiamento può anche verificarsi qui. Questo terzo If-Condition non è come i due precedenti.

Alla fine di questi tre swap, il valore medio dei tre valori in questione sarebbe un [alto], il cui contenuto originale avrebbe potuto essere modificato nel segmento di codice. Ad esempio, considera la sequenza non preventiva:

C b a

Sappiamo già che la mediana è b. Tuttavia, questo dovrebbe essere dimostrato. L'obiettivo qui è quello di ottenere la mediana di questi tre valori usando il segmento di codice sopra. Il primo If Statement confronta B e C. Se B è inferiore a C, le posizioni di B e C devono essere scambiate. B è inferiore a C, quindi il nuovo accordo diventa:

B c a

Si noti, i valori per l'indice più basso e l'indice medio sono cambiati. Il secondo se fosse stato paragonato a e b. Se A è inferiore a B, le posizioni di A e B devono essere scambiate. A è inferiore a B, quindi il nuovo accordo diventa:

A c b

Si noti, i valori per l'indice più alto e l'indice più basso sono cambiati. Il terzo se fosse stato paragonato a c e b. Se C è inferiore a B, le posizioni di C e B devono essere scambiate. C non è inferiore a B, quindi non si verificano scambiati. Il nuovo accordo rimane come il precedente, cioè:

A c b

B è la mediana, che è, a [alta], ed è il perno. Quindi, il perno nasce all'estremità estrema dell'elenco o sotto-list.

La funzione di scambio

Un'altra caratteristica necessaria per ordinamento rapido è la funzione di scambio. La funzione di scambio, scambia i valori di due variabili. Lo pseudocodice per la funzione di scambio è:

Definisci swap (x, y)
temp: = x
x: = y
y: = temp

Qui, xey si riferiscono ai valori effettivi e non alle copie.

L'ordinamento in questo articolo produrrà un elenco in cui il primo valore è il valore più piccolo e l'ultimo valore è il valore più grande.

Contenuto dell'articolo

  • Algoritmo di ordinamento rapido
  • Uno pseudocodice di partizione
  • Illustrazione di Sord Quick
  • Codice Java
  • Conclusione

Algoritmo di ordinamento rapido

Il modo normale di ordinare un elenco non orientato è considerare i primi due valori. Se non sono in ordine, mettili in ordine. Successivamente, considera i primi tre valori. Scansiona i primi due per vedere dove si adatta il terzo valore e si adatta in modo appropriato. Quindi, considera i primi quattro valori. Scansiona i primi tre valori per vedere dove si adatta il quarto valore e si adatta in modo appropriato. Continua con questa procedura fino a quando l'intero elenco non viene risolto.

Questa procedura, nota anche come tipo di forza bruta, nel linguaggio di programmazione del computer, è troppo lenta. L'algoritmo di ordinamento rapido viene fornito con una procedura molto più veloce.

I passaggi per l'algoritmo QuickSort sono i seguenti:

  1. Assicurati che ci siano almeno 2 numeri da ordinare nell'elenco non desiderato.
  2. Ottieni un valore centrale stimato per l'elenco, chiamato perno. La mediana, come descritto sopra, è un modo per ottenere il perno. Diversi modi hanno i loro vantaggi e svantaggi. - Vedi più tardi.
  3. Partizione dell'elenco. Ciò significa, posizionare il perno nell'elenco. In tal modo, tutti gli elementi a sinistra sono inferiori al valore del perno e tutti gli elementi a destra sono maggiori o uguali al valore del perno. Esistono diversi modi di partizionamento. Ogni metodo di partizione viene fornito con i suoi vantaggi e svantaggi. Il partizionamento si sta dividendo nel paradigma di divisione e conquista.
  4. Ripeti i passaggi 1, 2 e 3 in modo ricorsivo per le nuove coppie sotto-list che emergono fino a quando l'intero elenco non viene risolto. Questo sta conquistando nel paradigma di divisione e conquista.

Lo pseudocodice di ordinamento rapido è:

Algoritmo QuickSort (arr, basso, alto) è
se basso < high then
Pivot (basso, alto)
P: = partizione (arr, basso, alto)
QuickSort (arr, basso, p - 1)
QuickSort (arr, p + 1, alto)

Uno pseudocodice di partizione

Lo pseudocodice della partizione utilizzato in questo tutorial è:

La partizione dell'algoritmo (arr, basso, alto) è
Pivot: = arr [High]
i: = basso
J: = alto
Fare
Fare
++io
mentre (arr [i] < pivot)
Fare
--J
while (arr [j]> pivot)
se io < j)
scambia arr [i] con arr [j]
mentre io < j)
Swap arr [i] con arr [alto]
ritorno i

Nell'illustrazione di Sorved Sord che di seguito, questo codice viene utilizzato:

Illustrazione di Sord Quick

Prendi in considerazione il seguente elenco non desiderato (array) di lettere alfabetiche:

Q w e r t y u i o p

Per ispezione, l'elenco ordinato è:

E i o p q r t u w y

L'elenco ordinato sarà ora dimostrato, utilizzando i segmenti di algoritmo e pseudocodi sopra, dall'elenco non cortili:

Q w e r t y u i o p

Il primo perno è determinato da arr [0] = q, arr [4] = t e arr [9] = p, ed è identificato come q e posizionato all'estrema destra dell'elenco. Quindi, l'elenco con qualsiasi smistamento della funzione pivot diventa:

P w e r t y u i o q

L'attuale perno è Q. La procedura di perno ha fatto un po 'di smistamento e ha posto P nella prima posizione. L'elenco risultante deve essere riorganizzato (partizionato), in modo tale che tutti gli elementi a sinistra abbiano un valore più piccolo, quindi il perno e tutti gli elementi a destra del perno, siano uguali o superiori al perno. Il computer non può eseguire il partizionamento per ispezione. Quindi, lo fa usando gli indici e l'algoritmo di partizione sopra.

Gli indici bassi e alti ora sono 0 e 9. Quindi, il computer inizierà scansionando dall'indice 0 fino a raggiungere un indice, il cui valore è uguale o maggiore del perno e si interrompe temporaneamente. Scansionerà anche dall'estremità alta (a destra), indice 9, scendendo, fino a raggiungere un indice il cui valore è inferiore o uguale al perno e si ferma temporaneamente. Questo significa due posizioni di stop. Se io, la variabile dell'indice incrementale, dal basso non è ancora uguale o maggiore della variabile dell'indice decrescente, J da alto, allora questi due valori vengono scambiati. Nella situazione attuale, la scansione da entrambe le estremità si è fermata a W e O. Quindi l'elenco diventa:

P o e r t y u i w q

Il perno è ancora q. La scansione in direzioni opposte continua e si ferma di conseguenza. Se non sono ancora uguale o maggiore di J, vengono scambiati i due valori a cui la scansione di entrambe le estremità. Questa volta, la scansione da entrambe le estremità è fermata a R e io. Quindi, la disposizione dell'elenco diventa:

P o e i t y u r w q

Il perno è ancora q. La scansione in direzioni opposte continua e si ferma di conseguenza. Se non sono ancora uguale o maggiore di J, vengono scambiati i due valori a cui la scansione. Questa volta, la scansione da entrambe le estremità è fermata a T per io e io. Io e J abbiamo incontrato o attraversato. Quindi, non ci possono scambiare. L'elenco rimane lo stesso di:

P o e i t y u r w q

A questo punto, il perno, Q, deve essere inserito nella sua posizione finale nell'ordinamento. Questo viene fatto scambiando arr [i] con arr [high], scambiando t e q. L'elenco diventa:

P o e i q y u r w t

A questo punto, il partizionamento per l'intero elenco è terminato. Il pivot = q ha svolto il suo ruolo. Ora ci sono tre sotto-list, che sono:

P o e i q y u r w t

La partizione è divisione e conquista (ordinamento) nel paradigma. Q è nella sua corretta posizione di smistamento. Ogni elemento a sinistra di Q è più piccolo di Q e ogni elemento a destra di Q è più grande di Q. Tuttavia, l'elenco di sinistra non è ancora ordinato; E l'elenco giusto non è ancora ordinato. L'intera funzione di ordinamento rapido deve essere chiamata ricorsivamente per ordinare la sotto-list sinistra e la sotto-list destra. Questo richiamo di tipo rapido deve continuare; Nuovi sotto-listi si sviluppano fino a quando l'intero elenco originale non sarà completamente ordinato. Per ogni richiamo della funzione di ordinamento rapido, la sotto-elenco sinistra è seguita prima che sia frequentata la corrispondente sotto-elenco destro per. Un nuovo perno deve essere ottenuto per ogni sotto-list.

Per la sotto-list:

P o e i

Il perno (mediana) per p, o e i è determinato. Il perno sarebbe o. Per questa sotto-list e relativa all'elenco completo, il nuovo arr [basso] è arr [0] e il nuovo arr [alto] è l'ultimo arr [i-1] = arr [4-1] = arr [3], dove i è l'indice di perno finale della partizione precedente. Dopo che la funzione Pivot () è stata chiamata, il nuovo valore per pivot, pivot = o. Non confondere tra la funzione pivot e il valore per pivot. La funzione pivot può fare un po 'di smistamento e posizionare il perno all'estremo destro del sotto-list. Questa sotto-elenco diventa,

I p e o

Con questo schema, il perno termina sempre all'estremità destra della sotto-list o dell'elenco dopo la sua chiamata di funzione. La scansione da entrambe le estremità inizia da arr [0] e arr [3] fino a quando io e J si incontrano o si incrociano. Il confronto viene eseguito con pivot = o. Le prime fermate sono a P ed E. Sono scambiati e il nuovo sotto-list diventa:

I e p o

La scansione da entrambe le estremità continua e le nuove fermate sono a P per i e a e per j. Ora io e J abbiamo incontrato o attraversato. Quindi la sotto-list rimane la stessa di:

I e p o

Il partizionamento di una sotto-list o di un elenco termina quando il perno è stato messo nella sua posizione finale. Quindi, vengono scambiati i nuovi valori per arr [i] e arr [high]. Cioè, p e o sono scambiati. Il nuovo sotto-list diventa:

I e o p

O ora è nella sua posizione finale per l'intero elenco. Il suo ruolo di perno è finito. La sotto-list è attualmente divisa in altre tre liste, che sono:

I e o p

A questo punto, deve essere chiamato la prima specie di sotto-list a destra. Tuttavia, non verrà chiamato. Invece, verrà notato e riservato, per essere chiamato in seguito. Man mano che le dichiarazioni della funzione di partizionamento venivano eseguite, dalla parte superiore della funzione, è l'ordinamento rapido per la sotto-list di sinistra che deve essere chiamata ora (dopo che Pivot () è stato chiamato). Sarà chiamato per l'elenco:

CIOÈ

Inizierà cercando la mediana di I ed E. Qui, arr [low] = i, arr [mid] = i e arr [high] = e. Quindi la mediana, pivot, dovrebbe essere determinata dall'algoritmo di perno come, i. Tuttavia, lo pseudocodice di cui sopra determinerà il perno come E. Questo errore si verifica qui perché lo pseudocodice sopra è pensato per tre elementi e non due. Nell'implementazione seguente, c'è un certo aggiustamento al codice. La sotto-list diventa,

E i

Il perno termina sempre all'estremità destra della sotto-elenco o dell'elenco dopo la sua chiamata di funzione. La scansione da entrambe le estremità inizia da ARR [0] e ARR [1] esclusiva fino a quando io e J si incontrano o si incrociano. Il confronto è fatto con pivot = i. Le prime e solo fermate sono in I ed E: a I per I e a E per J. Ora io e J abbiamo incontrato o attraversato. Quindi, la sotto-list rimane la stessa di:

E i

Il partizionamento di una sotto-list o di un elenco termina quando il perno è stato messo nella sua posizione finale. Quindi, vengono scambiati i nuovi valori per arr [i] e arr [high]. Succede qui che arr [i] = i e arr [high] = i. Quindi, lo stesso valore viene scambiato con se stesso. Il nuovo sotto-list diventa:

E i

Ora sono nella sua posizione finale per l'intero elenco. Il suo ruolo di perno è finito. La sotto-list è ora divisa in altre due liste, che sono,

E i

Ora, i perni finora sono stati q, o e io. I perni finiscono nelle loro posizioni finali. Un sotto-elenco di un singolo elemento, come la P sopra, termina anche nella sua posizione finale.

A questo punto, la prima sotto-list a sinistra è stata completamente ordinata. E la procedura di smistamento è ora a:

E i o p q y u r w t

La prima sotto-list a destra:

Y u r w t

deve ancora essere risolto.

Conquistando la prima sotto-list a destra
Ricorda che è stato notato e riservato la chiamata rapida per la prima sotto-list destra invece di essere eseguito. A questo punto, verrà eseguito. E così, il nuovo arr [low] = arr [5] = arr [qpivotindex+1] e il nuovo arr [alto] rimane arr [9]. Una serie simile di attività che si sono verificate per la prima sotto-elenco di sinistra accadrà qui. E questa prima sotto-list a destra è ordinata per:

R t u w y

E l'elenco originale non orientato è stato ordinato per:

E i o p q r t u w y

Codice Java

Mettere l'algoritmo in Java è solo quello di mettere tutti i segmenti di pseudocodi sopra in metodi Java in una classe. Non dimenticare che ci deve essere un metodo principale () nella classe che chiamerà la funzione QuickSort () con l'array non desiderato.

Il metodo Pivot ()

Il metodo Java Pivot () che restituisce il valore, perno, dovrebbe essere:

void pivot (char arr [], int basso, int alto)
int mid = (basso + alto) / 2;
if (arr [mid] < arr[low])
Swap (arr, basso, metà);
if (arr [high] < arr[low])
Swap (arr, basso, alto);
if ((alto - basso)> 2)
if (arr [mid] < arr[high])
Swap (arr, metà, alto);

Il metodo Swap ()

Il metodo Swap () dovrebbe essere:

void swap (char arr [], int x, int y)
char temp = arr [x];
arr [x] = arr [y];
arr [y] = temp;

Il metodo QuickSort ()

Il metodo QuickSort () dovrebbe essere:

void QuickSort (char arr [], int basso, int alto)
Se (basso < high)
Pivot (arr, basso, alto);
int p = partizione (arr, basso, alto);
QuickSort (arr, basso, p - 1);
QuickSort (arr, p + 1, alto);

Il metodo di partizione ()

Il metodo Partition () dovrebbe essere:

int partizione (char arr [], int basso, int alto)
char pivot = arr [high];
int i = basso;
int j = alto;
Fare
Fare
++io;
mentre (arr [i] < pivot);
Fare
--J;
while (arr [j]> pivot);
se io < j)
scambia (arr, i, j);
mentre io < j);
Swap (arr, i, alto);
ritorno i;

Il metodo principale ()

Il metodo principale () può essere:

public static void main (string [] args)
char arr [] = 'q', 'w', 'e', ​​'r', 't', 'y', 'u', 'i', 'o', 'p';
TheClass QuickSort = new theClass ();
Quicksort.QuickSort (arr, 0, 9);
Sistema.fuori.println ("Gli elementi ordinati:");
per (int i = 0; i<10; i++)
Sistema.fuori.print (arr [i]); Sistema.fuori.stampa(");

Sistema.fuori.println ();

Tutti i metodi di cui sopra possono essere messi in una classe.

Conclusione

Quick Ord è un algoritmo di smistamento che utilizza il paradigma di divisione e conquista. Inizia dividendo un elenco non orientato in due o tre sotto-listi. In questo tutorial, Quick Ord ha diviso un elenco in tre sotto-list: una sotto-list di sinistra, un elenco centrale di un singolo elemento e una sotto-list destra. Conquistare in rapido ordinamento sta dividendo un elenco o una sotto-list durante l'ordinarlo, usando un valore per pivot. Questo tutorial ha spiegato un'implementazione di Sorvet Sort in the Java Computer Language.