El algoritmo de ordenación Shell está basada en el algoritmo de ordenación por inserción. Tiene mejores resultados que el algoritmo de Burbuja, Selección o Inserción directa.
El ShellSort ordena por inserción de subconjuntos del vector que están separados entre sí por iguales a la mitad del tamaño del vector, es decir, va armando subvectores de tamaño igual a k/2, e intercambiando valores, los cuales se van reduciendo rápidamente.
Ejemplo.
Tenemos el vector original.
Iteración 1:
Se formarán subvectores en saltos de 5, es decir el primer subvector esta compuesto par la posición 0, 5 y 11 del vector original (Color rojo).
El segundo subvector estará conformado por la posición 1 y 7 del vector original (Color verde).
Y así sucesivamente hasta tener todo los elementos en un subvector.
En total tenemos 5 subvectores, estos subvectores se ordenan internamente y regresan al vector original con las posiciones ordenadas.
Nuevo vector después de iteración 1:
Iteración 2:
Se modifica K, K=5/2=2.
Ahora los saltos se hacen de 2 en 2 para formar los nuevos subvectores.
De ésta forma se crean dos subvectores (rojo y verde), se ordenan internamente y se regresan con las posiciones ordenadas por cada subvector.
Se crea el nuevo vector con las nuevos números ordenados.
Iteración 3:
Se modifica k. K=2/2=1.
Cuando k=1 sólo podenos obtener 1 subvector; el vector original. Cuando k=1 Shell funaciona igual que el algoritmo de inserción dejando así el vector ordenado.
public static int[] ordenacionShell(int vec[]){
int cont=0;
final int N=vec.length;
int k=N/2;
while (k>=1){
for (int i = 0; i < k; i++){
//para cada subvector recorremos sus elementos
for (int j = k+i; j < N; j+= k)
{
int v = vec[j];
int n = j - k;
while (n>=0&& vec[n] >v){
vec[n + k] = vec[n];
n-=k;
}
vec[n + k] = v;
}
}
//obtenemos un nuevo salto
k /= 2;
}
return vec;
}
public class Shell {
public static void main(String[] args) {
int vec[]={45,17,23,67,21,55,8,18,89,26,58};
System.out.println("Vector original");
imprimirVector(vec);
System.out.println("\n");
vec=ordenacionShell(vec);
imprimirVector(vec);
}
public static int[] ordenacionShell(int vec[]){
int cont=0;
final int N=vec.length;
int k=N/2;
while (k>=1){
for (int i = 0; i < k; i++){
//para cada subvector recorremos sus elementos
for (int j = k+i; j < N; j+= k)
{
int v = vec[j];
int n = j - k;
while (n>=0&& vec[n] >v){
vec[n + k] = vec[n];
n-=k;
}
vec[n + k] = v;
}
}
//obtenemos un nuevo salto
k /= 2;
System.out.print("iteracion: "+(++cont)+": ");imprimirVector(vec);System.out.println();
}
return vec;
}
public static void imprimirVector(int vec[]){
for(int i=0;i<vec.length;i++){
System.out.print(vec[i]+" ");
}
}
}