Sezione dedicata agli algoritmi di ordinamento, merging e operazioni correlate. Tutti gl algoritmi di questa sezione hanno due varianti. Una che usa l'operatore '<' per confrontare gli elementi, l'altra che usa una funzione o un functor chiamato comp.
5.5.1: sort e stable_sort
L'algoritmo sort() ordina gli elementi compresi tra i due iteratori passati. Può essere utilizzato solo da container che hanno iteratori ad accesso casuale, come vector e deque.
Per l'ordinamento di list é dunque necessario usare la funzione membro list::sort().
L'algoritmo non é stabile, dunque se ci sono due o più elementi che dal punto di vista del comparatore sono uguali, non é detto che mantangano la posizione relativa iniziale. Nel caso peggiore le prestazioni di questo algoritmo possono degaradare, si può ricorrere a stable_sort() se questo può essere un problema. Sono resi disponibili due versioni di sort(), una usa l'operatore '<', l'altra permette di usare una funzione o un functor Compare.
Nell'esempio vediamo l'uso di sort e stable_sort nei due casi:
#include<iostream>
#include<algorithm>
#include<vector>
#include<ctime>
using namespace std;
void dump(const vector<double>& v) {
vector<double>::const_iterator it = v.begin();
while (it != v.end()) {
cout << *it++ << ' ';
}
cout << endl;
}
bool integerLess(double x, double y) {
return long(x) < long(y);
}
int main() {
vector<double> v(20);
srand(time(NULL));
for (size_t i = 0; i < v.size(); ++i) {
v[i] = (rand() % 3 + 1) + double((rand() % 100 + 1) / 1000.0);
}
random_shuffle(v.begin(), v.end());
cout << "Original sequence" << endl;
dump(v);
vector<double> unstable = v;
vector<double> stable = v;
cout << endl << "Sorting using the standard operator less" << endl;
// sorting with < operator:
stable_sort(stable.begin(), stable.end());
cout << "Stable sorting:" << endl;
dump(stable);
sort(unstable.begin(), unstable.end());
cout << "Unstable sorting:" << endl;
dump(unstable);
cout << endl << "Sorting with custom comparator" << endl;
unstable = v;
stable = v;
stable_sort(stable.begin(), stable.end(), integerLess);
cout << "stable sorting (integer key):" << endl;
dump(stable);
sort(unstable.begin(), unstable.end(), integerLess);
cout << "unstable sorting (integer key):\n";
dump(unstable);
}
Inizializziamo l'array con valori decimali casuali in modo che in molti condividano la stessa parte intera.
Quando usiamo l'operatore '<' non c'é differenza nel risultato nell'uso di sort e stable_sort, ma usando la nostra funzione integerLess, che compara i valori interi, notiamo che solo la stable_sort permetta di mantenere la posizione relativa tra gli elementi dopo l'ordinamento.
Nessun commento:
Posta un commento