tl; dr: È possibile implementare quicksort su una lista doppiamente collegata in modo efficiente? La mia comprensione prima di pensarci era, no, non è così.requisiti di iteratore di ordinamento rapido
L'altro giorno ho avuto l'opportunità di considerare i requisiti degli iteratori per gli algoritmi di ordinamento di base. Le unità base (N²) sono abbastanza semplici.
- Ordinamento di bolle - 2 iteratori di inoltro funzionano bene, uno dopo l'altro.
- Ordinamento inserzione - eseguiranno 2 iteratori bidirezionali. Uno per l'elemento out-of-order, uno per il punto di inserimento.
- Selezione sort - Un po 'più complicato ma gli iteratori in avanti possono fare il trucco.
Quicksort
L'introsort_loop in std :: sort (come nella GNU libreria/CV standard (1994)/Silicon Graphics (1996)) richiede di essere random_access.
__introsort_loop(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Size __depth_limit, _Compare __comp)
Come mi sono aspettato.
Ora, a un'ispezione più ravvicinata, non riesco a trovare il vero motivo per richiederlo per quicksort. L'unica cosa che richiede esplicitamente random_access_iterators è la chiamata std::__median
che richiede il calcolo dell'elemento intermedio. Il quicksort regolare, vaniglia non corrisponde a calcola la mediana.
Il partizionamento consiste in un assegno
if (!(__first < __last))
return __first;
Non
davvero un assegno utile per bidirectionals. Tuttavia si dovrebbe essere in grado di sostituire questo con un assegno nel precedente viaggio partizionamento (da sinistra a destra/destra a sinistra) con un semplice stato di
if (__first == __last) this_partitioning_is_done = true;
È possibile implementare quicksort abbastanza efficiente utilizzando iteratori solo bidirezionali ? La profondità ricorsiva può ancora essere protetta.
NB. Non ho ancora tentato un'implementazione effettiva.
Per l'ordinamento di inserimento, gli iteratori di inoltro sono sufficienti. È possibile utilizzare una combinazione di 'std :: rotate' e' std :: upper_bound' per implementare gli inserimenti, e entrambi gli ingredienti richiedono solo iteratori forward. È ancora O (N^2), naturalmente. – TemplateRex