[JAVA] Insertion sort che inizia dalla fine
Ciao a tutti, volevo scrivere un metodo insertion sort che però iniziasse ad analizzare gli elementi dal fondo invece che dall'inizio.. C'ho provato ma non ci riesco, o mi da out of bound oppure non me lo ordina.. Ho provato a simulare la cosa a mano ma mi incasino..
L'insertion sort standard è questo
Quello che ho scritto io e che non va è:
Dove sbaglio?
L'insertion sort standard è questo
public static void insertionSort(int[] a) {
int n = a.length;
for(int i = 1; i < n; i++) {
int x = a[i];
int j = i;
while(j > 0 && x < a[j-1]) {
a[j] = a[j-1];
j--;
}
a[j] = x;
}
}
Quello che ho scritto io e che non va è:
public static void insertionSortFine(int[] a) {
int n = a.length - 1;
for(int i = n; i >= 0; i--) {
int x = a[i];
int j = i;
while(j < 0 && x > a[j-1]) {
a[j] = a[j-1];
j++;
}
a[j] = x;
}
}
Dove sbaglio?
Risposte
Il ciclo for parte con i = n, poi accedi all'indice i dell'array, che è oltre la fine (da 0 a n-1). Il while invece è proprio sbagliato, se j < 0 a[j] e a[j-1] non sono indici validi.
Nell'insertion sort standard il ciclo for va da 1 a n-1 (dal secondo elemento all'ultimo), quindi in quello inverso deve andare da n-2 a 0 (dal penultimo elemento al primo).
Il while dice "dalla posizione corrente, scorri fino all'inizio finché non trovi un numero maggiore di x". Quindi va da j = i fino a j = 0, o si ferma prima se x < a[j-1].
L'inverso è "dalla posizione corrente, scorri fino alla fine finché non trovi un numero minore di x". Quindi va da j = i fino a j = n-2, o si ferma prima se x > a[j+1]. Nota che è j + 1, non j - 1, perché controlli l'elemento successivo nella direzione in cui stai scorrendo l'array (verso l'inizio nell'insertion sort standard, verso la fine in quello inverso).
Nell'insertion sort standard il ciclo for va da 1 a n-1 (dal secondo elemento all'ultimo), quindi in quello inverso deve andare da n-2 a 0 (dal penultimo elemento al primo).
Il while dice "dalla posizione corrente, scorri fino all'inizio finché non trovi un numero maggiore di x". Quindi va da j = i fino a j = 0, o si ferma prima se x < a[j-1].
L'inverso è "dalla posizione corrente, scorri fino alla fine finché non trovi un numero minore di x". Quindi va da j = i fino a j = n-2, o si ferma prima se x > a[j+1]. Nota che è j + 1, non j - 1, perché controlli l'elemento successivo nella direzione in cui stai scorrendo l'array (verso l'inizio nell'insertion sort standard, verso la fine in quello inverso).
for (int i = n-2; i >= 0; --i) {
int x = a[i];
int j = i;
while (j < n-1 && x > a[j+1]) {
a[j] = a[j+1];
j++;
}
a[j] = x;
}
In effetti era facile.. Grazie mille