Anterior Home Siguiente

Método de Shell (Shell Sort)

El método Shell (en honor a su descubridor) mejor del método de inserción simple ordenando subarrreglos del arreglo original en forma separada. Para crear estos nuevos subarreglos, se toman elementos saltados del areglo original en relación a incrementos predeterminados.

Por ejemplo suponiendo un arreglo X, y tomando un incremento (salto) igual a 5, se generarían los siguientes subarreglos:

Subarreglo 1:X[0] X[5] X[10] ...
Subarreglo 2:X[1] X[6] X[11] ...
Subarreglo 3:X[2] X[7] X[12] ...
Subarreglo 4:X[3] X[8] X[13] ...
etc.

Con un salto igual a 3 se obtendrían:

Subarreglo 1:X[0] X[3] X[6] ...
Subarreglo 2:X[1] X[4] X[7] ...
Subarreglo 3:X[2] X[5] X[8] ...
Subarreglo 4:X[3] X[6] X[9] ...
etc.

Lo habitual es tomar un valor de incremento, y ordenar mediante inserción los subarreglos obtenidos. Luego se toma otro valor de incremento, y se ordenan ahora los asubarreglos generados a partir de este incremento. Y así sucesivamente para diferentes valores de incremento o salto.

Supongamos que tenemos el siguienmte arreglo:

2557483712928633

y que se elige la secuencia de incrementos (5,3,1), los archivos a ordenar para esta secuencia serían:

con incremento = 5:

(x[0], x[5])
(x[1], x[6])
(x[2], x[7])
(x[3])
(x[4])

con incremento = 3:

(x[0], x[3], x[6])
(x[1], x[4], x[7])
(x[2], x[5])

con incremento = 1:

(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7])

A continuación se muestra el resultado del ordenamiento Shell sobre este arreglo. Las líneas indican los subarreglos que se procesan por separado.

arreglo originalo2557483712928633
paso 1
salto = 5
o2557483712928633
paso 2
salto = 3
2557333712928648
paso 3
salto = 1
2512333748928657
Arreglo ordenado2512333748578692

Habitualmente lo que se hace es generar un arreglo que contenga los incrementos. Suponiendo que se tiene un arreglo con los incrementos, a continuación se muestra un ejemplo del método Shell en el siguiente fragmento de código en C:

.
.
.
int X[n]; /* será el número de elementos del arreglo */
int i,j,K /* K será el elemento que se inserte para mantener el orden */
int incre[numinc]; /* incre contiene la secuencia de incrementos,
		         y numinc es el número total de incrementos */
int salto, numi;
.
.
.
for (numi=0;numi<numinc;numi++)
{
	salto = incre[numi]; /* salto es el incremento actual */
	for (j=salto;j<n;j++)
	{	
		K=X[j];
		for(i=j-salto;i>=0&&K<X[i];i-=salto)
		{
			X[i+salto]=X[i];
			X[i]=K;
		}
	}
}
.
.
.

Se recomienda utilizar secuencias de incrementos, donde ellos sean numeros primos relativos, es decir, que no tengan divisores comunes entre ellos distintos del 1.

Ejemplo completo en C: shell.zip


Anterior Home Siguiente



© 2000 Made in Bufoland