hablemos de cómo funciona:
Necesitamos un punto pivotal (ósea por donde iniciar).
para ello Shell usa esto: MAXC/2 para estar en la mitad del array.
(como for solo apunta a una posición y sabiendo que al dividir enteros impares podemos llegar a tener resultado con decimal es que MAXC se declara como const int, así al dividir, si tiene un decimal, según sea menor o mayor a .5 lo sube o lo deja como esta, así como las calificaciones)
Una vez tenemos la división, empieza las iteraciones de manera que compara el valor del punto pivotal (ósea el número de medio), con el primero valor del array, si el pivote es menor al primer valor del array, permuta sus lugares, si no pues los deja y se recorre.
[3] [5] [8] [1] [0] [10] [12] [7] [15] Posición Inicial
[3] [5] [8] [1] [0] [10] [12] [7] [15] Posición siguiente
Una vez recorrido todo el array divide a la mitad el valor de su pivote, algo así como (MAXC/2)/2 esto para acordar distancias y asegurar un mejor ordenamiento, una vez hecho eso hace lo mismo [compara el valor del punto pivotal (ósea el número de medio), con el primero valor del array].
Pero aquí hace algo interesante, como reducimos el tamaño del pivote ósea:
[3] [5] [8] [1] [0] [10] [12] [7] [15] Posición Inicial
[3] [5] [8] [1] [0] [10] [12] [7] [15] Posición siguiente
Podemos comparar mas datos por iteración, es decir, nuestro pivote indica en si la separación entre datos que hay entre nuestro pivote a comparar y la posición que comparamos, con ello, el algoritmo se permite comparar mas datos.
Si nuestro valor en pivote es menor al valor que estamos apuntando, el valor apuntando pasa a la posición donde esta nuestro apuntador, y lo que tenemos en apuntador aun, se sigue comparando con el valor que esta separado en (MAXC/2)/2 posicion, a lado del que comparamos y hace lo mismo, si no es menor pues nuestro pivote permuta con esa última posición y se recorre.
//Aqui a de sonar un poco enredado, pero razon por la cual tenemos la variable temp la cual nos hace el favor de guardarnos lo que tiene pivote, en lo que movemos los otros datos de lugar, asi podemos cambiar de posicion y ordenar los datos.
Temp basicamente es quien nos hace la magia de ordenar los datos, junto con los for claro.
Este proceso se repite hasta que no puede dividir mas entre 2 y quede un entero como resultado (claro esta hehe) por que intuitivamente sabemos que ya los datos en este punto ya deben estar ordenados y ahí termina y despliega los datos.
Desventaja:
Independientemente de como trabaja, es un algoritmo de incremento lineal, quiere decir entre mas aumenta el array que hay que ordenar mayor es la cantidad de iteraciones que debe realizar, en comparación de sus hermanos Sort que lleven la lógica DIVIDE & CONQUER (Lo cual ya les comenté en el foro pasado).
Tiene ventaja contra Bubble Sort ya que tiene un pivote que reduce el tamaño de iteraciones, al “dividir” en mitad, e ir ordenando.
Pero!!!, tiene su ventaja, cuando hablamos de cantidades pequeñas de datos, al tener las bases de lo que viene siendo Divide&Conquer, optimiza su tiempo s, por lo que puede ganar a algoritmos como Merge o Quick Sort.
https://www.youtube.com/watch?v=qzXAVXddcPU
Entonces?..
Si queremos implementar este u otros Sorts en operación debemos pensar en que información estamos manejando, a qué velocidad crecerá la info (esto según el negocio que va enfocado),
o si es info que rara vez crece o no varia mucho y no necesitamos que sea tan rápida la consulta.
Para SHELL no es pensado en rapidez ni para DataCenters, es como un intermedio.
`using namespace std;
#include <iostream>
int main()
{ const int MAXC=7;
int array[MAXC]={6,1,5,2,3,4,0};
int cont,pasos,temp,i;
for(cont=MAXC/2;cont!=0;cont/=2)
for(pasos=1;pasos!=0;)
{
pasos=0;
for(i=cont;i<MAXC;i++)
if(array[i-cont]>array[i])
{
temp=array[i];
array[i]=array[i-cont];
array[i-cont]=temp;
pasos++;
}
}
cout<<"Arreglo ordenado: ";
for(int i=0;i<MAXC;i++)
{
cout<<array[i]<<" ";
}
}`