Ordenación por ShellSort

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.

Código del algoritmo ShellSort

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;
        }

Implementación

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]+" ");
                }
        }

}