merge sort c with examples
Tecnica di ordinamento di unione C ++.
L'algoritmo di ordinamento unione utilizza il ' dividere e conquistare 'Strategia in cui dividiamo il problema in sottoproblemi e risolviamo questi sottoproblemi individualmente.
Questi problemi secondari vengono quindi combinati o fusi insieme per formare una soluzione unificata.
=> Leggi qui la popolare serie di formazione C ++.
Cosa imparerai:
migliori siti per guardare anime doppiati
- Panoramica
- Algoritmo generale
- Pseudo codice per l'ordinamento di unione
- Illustrazione
- Ordinamento di unione iterativo
- Analisi della complessità dell'algoritmo di ordinamento di unione
- Conclusione
- Lettura consigliata
Panoramica
L'ordinamento di unione viene eseguito utilizzando i seguenti passaggi:
# 1) L'elenco da ordinare viene diviso in due array di uguale lunghezza dividendo l'elenco sull'elemento centrale. Se il numero di elementi nell'elenco è 0 o 1, l'elenco viene considerato ordinato.
#Due) Ciascun elenco secondario viene ordinato individualmente utilizzando l'ordinamento di unione in modo ricorsivo.
# 3) Le sottoliste ordinate vengono quindi combinate o unite insieme per formare un elenco ordinato completo.
Algoritmo generale
Di seguito viene fornito lo pseudocodice generale per la tecnica di ordinamento unione.
Dichiarare un array Arr di lunghezza N
Se N = 1, Arr è già ordinato
Se N> 1,
Sinistra = 0, destra = N-1
Trova il centro = (sinistra + destra) / 2
Chiama merge_sort (Arr, left, middle) => ordina la prima metà in modo ricorsivo
Chiama merge_sort (Arr, middle + 1, right) => ordina la seconda metà in modo ricorsivo
Chiama merge (Arr, left, middle, right) per unire array ordinati nei passaggi precedenti.
Uscita
Come mostrato nello pseudo codice sopra, nell'algoritmo di merge sort dividiamo l'array a metà e ordiniamo ogni metà usando merge sort in modo ricorsivo. Una volta che i sotto-array sono stati ordinati individualmente, i due sotto-array vengono uniti insieme per formare un array ordinato completo.
Pseudo codice per l'ordinamento di unione
Di seguito è riportato lo pseudo codice per la tecnica di ordinamento unione. Innanzitutto, abbiamo una procedura di merge sort per dividere l'array in due metà ricorsivamente. Quindi abbiamo una routine di unione che unirà gli array più piccoli ordinati per ottenere un array ordinato completo.
procedure mergesort( array,N ) array – list of elements to be sorted N – number of elements in the list begin if ( N == 1 ) return array var array1 as array = a(0) ... a(N/2) var array2 as array = a(N/2+1) ... a(N) array1 = mergesort(array1) array2 = mergesort(array2) return merge( array1, array2 ) end procedure procedure merge(array1, array2 ) array1 – first array array2 – second array begin var c as array while ( a and b have elements ) if ( array1(0) > array2(0) ) add array2 (0) to the end of c remove array2 (0) from array2 else add array1 (0) to the end of c remove array1 (0) from array1 end if end while while ( a has elements ) add a(0) to the end of c remove a(0) from a end while while ( b has elements ) add b(0) to the end of c remove b(0) from b end while return c end procedure
Vediamo ora di illustrare la tecnica di merge sort con un esempio.
Illustrazione
L'illustrazione sopra può essere mostrata in una forma tabellare di seguito:
Passaggio | Elenco non ordinato | dividere | Elenco ordinato |
---|---|---|---|
1 | {12, 23,2,43,51,35,19,4} | {12,23,2,43} {51,35,19,4} | {} |
Due | {12,23,2,43} {51,35,19,4} | {12.23} {2.43} {51.35} {19.4} | {} |
3 | {12.23} {2.43} {51.35} {19.4} | {12.23} {2.43} {35.51} {4.19} | {12.23} {2.43} {35.51} {4.19} |
4 | {12.23} {2.43} {35.51} {4.19} | {2,12,23,43} {4,19,35,51} | {2,12,23,43} {4,19,35,51} |
5 | {2,12,23,43} {4,19,35,51} | {2,4,12,19,23,35,43,51} | {2,4,12,19,23,35,43,51} |
6 | {} | {} | {2,4,12,19,23,35,43,51} |
Come mostrato nella rappresentazione sopra, prima l'array è diviso in due sotto-array di lunghezza 4. Ogni sotto-array è ulteriormente diviso in altri due sotto-array di lunghezza 2. Ogni sotto-array è poi ulteriormente suddiviso in un sotto-array di un elemento ciascuno. L'intero processo è il processo 'Dividi'.
Dopo aver diviso l'array in sotto-array di singoli elementi ciascuno, ora dobbiamo unire questi array in ordine ordinato.
Come mostrato nell'illustrazione sopra, consideriamo ogni sottoarray di un singolo elemento e prima combiniamo gli elementi per formare sotto-array di due elementi in ordine ordinato. Successivamente, i sottoarray ordinati di lunghezza due vengono ordinati e combinati per formare due sotto-array di lunghezza quattro ciascuno. Quindi combiniamo questi due sotto-array per formare un array ordinato completo.
Ordinamento di unione iterativo
L'algoritmo o la tecnica di merge sort che abbiamo visto sopra utilizza la ricorsione. È anche noto come ' merge sort ricorsivo '.
Sappiamo che le funzioni ricorsive usano lo stack di chiamate di funzione per memorizzare lo stato intermedio della funzione chiamante. Memorizza anche altre informazioni di contabilità per parametri ecc. E pone un sovraccarico in termini di memorizzazione del record di attivazione della chiamata della funzione e della ripresa dell'esecuzione.
Tutti questi overhead possono essere eliminati se usiamo funzioni iterative invece di quelle ricorsive. L'algoritmo di merge sort di cui sopra può anche essere convertito facilmente in passaggi iterativi utilizzando loop e processi decisionali.
Come l'ordinamento di unione ricorsivo, anche l'ordinamento di unione iterativo ha complessità O (nlogn), quindi per quanto riguarda le prestazioni, si comportano alla pari tra loro. Siamo semplicemente in grado di abbassare le spese generali.
In questo tutorial, ci siamo concentrati sull'ordinamento di tipo merge ricorsivo e successivamente implementeremo l'ordinamento di tipo merge ricorsivo utilizzando i linguaggi C ++ e Java.
Di seguito è riportata un'implementazione della tecnica di ordinamento unione utilizzando C ++.
#include using namespace std; void merge(int *,int, int , int ); void merge_sort(int *arr, int low, int high) { int mid; if (low num; cout<<'Enter '<myarray(i); } merge_sort(myarray, 0, num-1); cout<<'Sorted array
'; for (int i = 0; i < num; i++) { cout< Produzione:
Immettere il numero di elementi da ordinare: 10
Immettere 10 elementi da ordinare: 101 10 2 43 12 54 34 64 89 76
Matrice ordinata
2 10 12 34 43 54 64 76 89101
In questo programma abbiamo definito due funzioni, merge_sort e partire . Nella funzione merge_sort, dividiamo l'array in due array uguali e chiamiamo la funzione merge su ciascuno di questi sotto array. Nella funzione merge, eseguiamo l'ordinamento effettivo su questi sotto array e quindi li uniamo in un array ordinato completo.
Successivamente, implementiamo la tecnica Merge Sort in linguaggio Java.
class MergeSort { void merge(int arr(), int beg, int mid, int end) { int left = mid - beg + 1; int right = end - mid; int Left_arr() = new int (left); int Right_arr() = new int (right); for (int i=0; i Produzione:
Array di input
101 10 2 43 12 54 34 64 89 76
Matrice ordinata utilizzando l'ordinamento di unione
2 10 12 34 43 54 64 76 89101
Anche nell'implementazione Java, usiamo la stessa logica usata nell'implementazione C ++.
L'ordinamento di unione è un modo efficiente per ordinare gli elenchi e viene utilizzato principalmente per ordinare gli elenchi collegati. Poiché utilizza un approccio divide et impera, la tecnica di ordinamento merge funziona in modo altrettanto efficiente per array più piccoli e più grandi.
Analisi della complessità dell'algoritmo di ordinamento di unione
Sappiamo che per eseguire l'ordinamento utilizzando l'ordinamento di unione, prima dividiamo l'array in due metà uguali. Questo è rappresentato da “log n” che è una funzione logaritmica e il numero di passi compiuti è al massimo log (n + 1).
Successivamente per trovare l'elemento centrale dell'array, è necessario un passaggio singolo, ad esempio O (1).
Quindi per unire i sotto-array in un array di n elementi, impiegheremo O (n) quantità di tempo di esecuzione.
Pertanto il tempo totale per eseguire l'ordinamento di unione sarà n (log n + 1), che ci dà la complessità temporale di O (n * logn).
Complessità temporale nel caso peggiore O (n * log n) Migliore complessità temporale del caso O (n * log n) Complessità temporale media O (n * log n) Complessità spaziale Su)
La complessità temporale per l'ordinamento di unione è la stessa in tutti e tre i casi (peggiore, migliore e medio) poiché divide sempre l'array in sotto-array e quindi unisce i sotto-array prendendo tempo lineare.
L'ordinamento di unione occupa sempre una quantità di spazio uguale a quella degli array non ordinati. Pertanto, quando l'elenco da ordinare è un array, l'ordinamento di tipo merge non dovrebbe essere utilizzato per array molto grandi. Tuttavia, l'ordinamento di tipo merge può essere utilizzato in modo più efficace per l'ordinamento di elenchi collegati.
Conclusione
L'ordinamento di tipo merge utilizza la strategia 'divide et impera' che divide l'array o l'elenco in numerosi sotto-array e li ordina individualmente e quindi si fonde in un array ordinato completo.
L'ordinamento di tipo merge funziona più velocemente di altri metodi di ordinamento e funziona anche in modo efficiente per array sempre più piccoli.
Esploreremo di più sull'ordinamento rapido nel nostro prossimo tutorial!
=> Guarda qui la guida di formazione per principianti C ++.
Lettura consigliata
- Metodo MongoDB Sort () con esempi
- Comando di ordinamento Unix con sintassi, opzioni ed esempi
- Ordinamento della shell in C ++ con esempi
- Ordinamento heap in C ++ con esempi
- Ordinamento di selezione in C ++ con esempi
- Bubble Sort in C ++ con esempi
- Ordinamento di inserzione in C ++ con esempi
- Ordinamento rapido in C ++ con esempi