Está en la página 1de 14

MODOS DE ORDENAMIENTO C++

1. Ordenamiento burbuja:
Este es el algoritmo más sencillo probablemente. Ideal para empezar. Consiste en ciclar
repetidamente a través de la lista, comparando elementos adyacentes de dos en dos. Si
un elemento es mayor que el que está en la siguiente posición se intercambian.
1. for (i=1; i<TAM; i++)
2. for j=0 ; j<TAM - 1; j++)
3. if (lista[j] > lista[j+1])
4. temp = lista[j];
5. lista[j] = lista[j+1];
6. lista[j+1] = temp;

2. Ordenamiento por selección:


^
Este algoritmo también es sencillo. Consiste en lo siguiente:
 Buscas el elemento más pequeño de la lista.
 Lo intercambias con el elemento ubicado en la primera posición de la lista.
 Buscas el segundo elemento más pequeño de la lista.
 Lo intercambias con el elemento que ocupa la segunda posición en la lista.
 Repites este proceso hasta que hayas ordenado toda la lista.
1. for (i=0; i<TAM - 1; i++)
2. pos_men = Menor(lista, TAM, i);
3. temp = lista[i];
4. lista[i] = lista [pos_men];
5. lista [pos_men] = temp;

3. Ordenamiento por inserción:


El ordenamiento por inserción es una manera muy natural de ordenar para un ser
humano, y puede usarse fácilmente para ordenar un mazo de cartas numeradas en forma
arbitraria.
La idea de este algoritmo de ordenación consiste en ir insertando un elemento de la lista
ó un arreglo en la parte ordenada de la misma, asumiendo que el primer elemento es la
parte ordenada, el algoritmo ira comparando un elemento de la parte desordenada de la
lista con los elementos de la parte ordenada, insertando el elemento en la posición
correcta dentro de la parte ordenada, y así sucesivamente hasta obtener la lista
ordenada.
1. for (i=1; i<TAM; i++)
2. temp = lista[i];
3. j = i - 1;
4. while ( (lista[j] > temp) && (j >= 0) )
5. lista[j+1] = lista[j];
6. j--;
7. lista[j+1] = temp;

4. Ordenamiento rápido(Quicksort):
El ordenamiento rápido (tambien llamado ordenamiento de Hoare o quicksort en inglés)
es un algoritmo creado por el científico británico en computación Tony Hoare y basado
en la técnica de divide y vencerás. Esta es la técnica quizás la más eficiente y en ella que
en la mayoría de los casos da mejores resultados
El algoritmo fundamental es el siguiente:
Elegir un elemento de la lista de elementos a ordenar, al que llamaremos pivote.
Resituar los demás elementos de la lista a cada lado del pivote, de manera que a un lado
queden todos los menores que él, y al otro los mayores. En este momento, el pivote
ocupa exactamente el lugar que le corresponderá en la lista ordenada.
La lista queda separada en dos sublistas, una formada por los elementos a la izquierda
del pivote, y otra por los elementos a su derecha.
Repetir este proceso de forma recursiva para cada sublista mientras éstas contengan más
de un elemento. Una vez terminado este proceso todos los elementos estarán ordenados.

// Inicialización de variables
1. elem_div = lista[sup];
2. i = inf - 1;
3. j = sup;
4. cont = 1;

// Verificamos que no se crucen los límites


5. if (inf >= sup)
6. retornar;

// Clasificamos la sublista
7. while (cont)
8. while (lista[++i] < elem_div);
9. while (lista[--j] > elem_div);
10. if (i < j)
11. temp = lista[i];
12. lista[i] = lista[j];
13. lista[j] = temp;
14. else
15. cont = 0;

// Copiamos el elemento de división


// en su posición final
16. temp = lista[i];
17. lista[i] = lista[sup];
18. lista[sup] = temp;

// Aplicamos el procedimiento
// recursivamente a cada sublista
19. OrdRap (lista, inf, i - 1);
20. OrdRap (lista, i + 1, sup);

5. Ordenamiento de burbuja bidireccional

El ordenamiento de burbuja bidireccional (también llamado "método de la sacudida" o


"coctail sort" o "shaker sort") es un algoritmo de ordenamiento que surge como una
mejora del algoritmo ordenamiento de burbuja.
Si ya habéis visto cómo funciona el algoritmo de ordenación por burbuja habréis
observado que los números grandes se están moviendo rápidamente hasta al final de la
lista (estas son las "liebres"), pero que los números pequeños (las "tortugas") se mueven
sólo muy lentamente al inicio de la lista.
Una solución es de ordenar con el método de burbuja y cuando llegamos al final de la
primera iteración, no volver a realizar el cálculo desde el principio sino que
empezaremos desde el final hasta al inicio. De esta manera siempre se consigue que
tanto los números pequeños como los números grandes se desplacen a los extremos de la
lista lo más rápido posible.
1. PROCEDIMIENTO cocktail_sort (VECTOR a [1:n])
2. 
3. dirección ← 'frontal', comienzo ← 1, fin ← n-1, actual ← 1
4.
5. REPETIR
6. permut ← FALSO
7. REPETIR
8. SI a[actual] > a[actual + 1] ENTONCES
9. intercambiar a[actual] Y a[actual + 1]
10. permut ← VERDADERO
11. FIN SI  
12. SI (dirección='frontal') ENTONCES
13. actual ← actual + 1
14. SI NO
15. actual ←actual – 1
16. FIN SI
17. MIENTRAS
QUE ((dirección='frontal') Y (actual<fin)) OU ((dirección='final) O (actual>comienzo))
18. SI (dirección='frontal') ENTONCES
19. dirección ← 'final'
20. fin ← fin - 1
21. SI NO
22. dirección ← 'frontal'
23. comienzo ← comienzo + 1
24. FIN SI
25. MIENTRAS permut = VERDADERO
26.
27. FIN PROCEDIMIENTO
6. Ordenamiento Gnome

El algoritmo de ordenación conocido como Gnome_sort fue inventada por Hamid


Sarbazi-Azad, (profesor de la universidad de Sharif, una de las mayores universidades de
Irán) quien lo desarrolló en el año 2000 y al que llamó Stupid sort (Ordenamiento
estúpido).
Cuando Dick Grune lo reinventó y documentó, no halló evidencias de que existiera y en
palabras suyas, dijo de él "the simplest sort algorithm" (es el algoritmo más simple) y
quizás tenga razón, pues lo describió en sólo cuatro líneas de código. Dick Grune se basó
en los gnomos de jardín holandés, en como se colocan en los maceteros y de ahí también
el nombre que le dio.
El algoritmo es similar a la ordenación por inserción , excepto que , en lugar de insertar
directamente el elemento a su lugar apropiado , el algoritmo realiza una serie de
permutaciones , como en el ordenamiento de burbuja.

1. PROCEDIMIENTO Gnome_sort(vector[])
2. pos := 1
3. MIENTRAS pos < longitud(vector)
4. SI (vector[pos] >= vector[pos-1])
5. pos := pos + 1
6. SI NO
7. intercambiar vector[pos] Y vector[pos-1]
8. SI (pos > 1)
9. pos := pos - 1
10. FIN SI
11. FIN SI
12. FIN MIENTRAS
FIN PROCEDIMIENTO
7. Ordenación del peine o de Dobosiewicz

En 1980, Wlodzimierz Dobosiewicz propuso este algoritmo en su breve artículo "An


Efficient Variation of Bubble Sort", Information Processing Letters, vol. 11, num. 1, 1980.
En él escribió literalmente: "Bubble sort can be improved in yet another way, which is
similar to Shell’s version of the insertion sort." ("La ordenación por burbuja se puede
mejorar de otra manera adicional, que es similar a la versión de Shell de la ordenación
por inserción").
Posteriormente fue redescubierto y popularizado por Stephen Lacey y Richard Box en un
artículo publicado por la revista Byte en abril de 1991.
En el ordenamiento de burbuja, cuando dos elementos cualquiera se comparan,
siempren tienen un espacio (distancia entre ellos) de 1. La idea básica del algoritmo
CombSort es que el espacio pueda ser mucho mayor de uno.
El ordenamiento Shell también se basa en esta idea, pero es una modificación del
algoritmo de ordenamiento por inserción más que del algoritmo de ordenamiento de
burbuja.

1. PROCEDIMIENTO comb_sort ( VECTOR a[1:n])
2. gap ← n
3. REPETIR
4.     permut ← FALSO
5.     gap ← gap / 1.3
6.     SI gap < 1 ENTONCES gap ← 1
7.     PARA i VARIANDO DE 1 HASTA n CON INCRECREMENT DE gap HACER
8.         SI a[i] > a[i+gap] ENTONCES
9.             intercambiar a[i] Y a[i+gap]
10.             permut ← VERDADERO
11.         FIN SI
12.     FIN POUR
13. MIENTRAS QUE permut = VERDADERO O gap > 1

8. Ordenación Shell:
La ordenación de Shell pertenece a los métodos de clasificación avanzados, nombrado
así en honor del ingeniero y matemático estadounidense Donald Shell que la propuso en
1959.
Este método utiliza una segmentación entre los datos. Funciona comparando elementos
que estén distantes; la distancia entre comparaciones decrece conforme el algoritmo se
ejecuta hasta la ultima fase, en la cual se comparan los elementos adyacentes, por esta
razón se le llama ordenación por disminución de incrementos.
La ordenación de Shell usa una secuencia, h1, h2, . . ., ht, conocida como la secuencia de
incrementos. Al principio de todo proceso, se fija una secuencia decreciente de
incrementos. Cualquier secuencia funcionará en tanto que empiece con un incremento
grande, pero menor al tamaño del arreglo de los datos a ordenar, y que el último valor de
dicha secuencia sea 1.

1. PROCEDURE tri_Insertion ( Tableau a[1:n],gap,debut)
2.     POUR i VARIANT DE debut A n AVEC UN PAS gap FAIRE
3.         INSERER a[i] à sa place dans a[1:i-1];
4. FIN PROCEDURE;
5.  
6. PROCEDURE tri_shell ( Tableau a[1:n])
7.     POUR gap DANS (6,4,3,2,1) FAIRE
8.        POUR debut VARIANT DE 0 A gap - 1 FAIRE
9.           tri_Insertion(Tableau,gap,debut);
10.        FIN POUR;
11.     FIN POUR;
12. FIN PROCEDURE;

9. Merge Sort

El método Quicksort divide la estructura en dos y ordena cada mitad recursivamente. El


caso del MergeSort es el opuesto, es decir, en éste método de unen dos estructuras
ordenadas para formar una sola ordenada correctamente.

Tiene la ventaja de que utiliza un tiempo proporcional a: n log (n), su desventaja radica
en que se requiere de un espacio extra para el procedimiento.

Este tipo de ordenamiento es útil cuando se tiene una estructura ordenada y los nuevos
datos a añadir se almacenan en una estructura temporal para después agregarlos a la
estructura original de manera que vuelva a quedar ordenada.

/*recibe el arreglo a ordenar un índice l que indica el límite inferior del arreglo a ordenar
y un índice r que indica el límite superior*/

void mergesort(int a[], int l, int r)


{
int i,j,k,m,b[MAX];
if (r > l)
{
m = (r+l) /2;
mergesort(a, l, m);
mergesort(a, m+1, r);
for (i= m+1; i > l;i--)
b[i-1] = a[i-1];
for (j= m; j < r;j++)
b[r+m-j] = a[j+1];
for (k=l ; k <=r; k++)
if(b[i] < b[j])
a[k] = b[i++];
else
a[k] = b[j--];
}
}

a = {a,s,o,r,t,i,n,g,e,x,a,m,p,l,e}
{a,s,
o,r,
a,o,r,s,
i,t,
g,n,
g,i,n,t,
a,g,i,n,o,r,s,t,
e,x,
a,m,
a,e,m,x,
l,p,
e,l,p}
a,e,e,l,m,p,x}

a = {a,a,e,e,g,i,l,m,n,o,p,r,s,t,x}

10. Heap sort

Este método garantiza que el tiempo de ejecución siempre es de:

O(n log n)

El significado de heap en ciencia computacional es el de una cola de prioridades (priority


queue). Tiene las siguientes características:

 Un heap es un arreglo de n posiciones ocupado por los elementos de la cola.


(Nota: se utiliza un arreglo que inicia en la posición 1 y no en cero, de tal manera
que al implementarla en C se tienen n+1 posiciones en el arreglo.)
 Se mapea un árbol binario de tal manera en el arreglo que el nodo en la posición i
es el padre de los nodos en las posiciones (2*i) y (2*i+1).
 El valor en un nodo es mayor o igual a los valores de sus hijos. Por consiguiente,
el nodo padre tiene el mayor valor de todo su subárbol.

Heap Sort consiste esencialmente en:

 convertir el arreglo en un heap


 construir un arreglo ordenado de atrás hacia adelante (mayor a menor) repitiendo
los siguientes pasos:
o sacar el valor máximo en el heap (el de la posición 1)
o poner ese valor en el arreglo ordenado
o reconstruir el heap con un elemento menos
 utilizar el mismo arreglo para el heap y el arreglo ordenado.

/* Recibe como parámetros un arreglo a ordenar y un entero que indica el numero de


datros a ordenar */

void heapsort(int a[], int N)


{
int k;
for(k=N/2; k>=1; k--)
downheap(a,N,k);
while(N > 1)
{
swap(a,1,N);
downheap(a,--N,1);
}
}

/* el procedimiento downheap ordena el &aacure;rbol de heap para que el nodo padre


sea mayor que sus hijos */

void downheap(int a[], int N, int r)


{
int j, v;
v = a[r];
while (r <= N/2)
{
j = 2*r;
if(j < N && a[j] < a[j+1]);
j++;
if( v >= a[j])
break;
a[r] = a[j];
r = j;
}
a[r] = v;
}
11. Ordenamiento de raíz (radix sort).

Este ordenamiento se basa en los valores de los dígitos reales en las representaciones de
posiciones de los números que se ordenan.
Reglas para ordenar.

 Empezar en el dígito más significativo y avanzar por los dígitos menos


significativos mientras coinciden los dígitos correspondientes en los dos números.

 El número con el dígito más grande en la primera posición en la cual los dígitos de
los dos números no coinciden es el mayor de los dos (por supuesto sí coinciden
todos los dígitos de ambos números, son iguales).

#include
#include
#define NUMELTS 20

void radixsort(int x[], int n)


{
int front[10], rear[10];
struct {
int info;
int next;
} node[NUMELTS];
int exp, first, i, j, k, p, q, y;

/* Inicializar una lista viculada */


for (i = 0; i < n-1; i++) {
node[i].info = x[i];
node[i].next = i+1;
} /* fin del for */
node[n-1].info = x[n-1];
node[n-1].next = -1;
first = 0; /*first es la cabeza de la lista vinculada */
for (k = 1; k < 5; k++) {
/* Suponer que tenemos n£meros de cuatro dÁgitos */
for (i = 0; i < 10; i++) {
/*Inicializar colas */
rear[i] = -1;
front[i] = -1;
} /*fin del for */
/* Procesar cada elemento en la lista */
while (first != -1) {
p = first;
first = node[first].next;
y = node[p].info;
/* Extraer el kâsimo dÁgito */
exp = pow(10, k-1); /* elevar 10 a la (k-1)âsima potencia */
j = (y/exp) % 10;
/* Insertar y en queue[j] */
q = rear[j];
if (q == -1)
front[j] = p;
else
node[q].next = p;
rear[j] = p;
} /*fin del while */

/* En este punto, cada registro est en su cola bas ndose en el dÁgito k


Ahora formar una lista £nica de todos los elementos de la cola. Encontrar
el primer elemento. */
for (j = 0; j < 10 && front[j] == -1; j++);
;
first = front[j];

/* Vincular las colas restantes */


while (j <= 9) { /*Verificar si se ha terminado */
/*Encontrar el elemento siguiente */
for (i = j+1; i < 10 && front[i] == -1; i++);
;
if (i <= 9) {
p = i;
node[rear[j]].next = front[i];
} /* fin del if */
j = i;
} /* fin del while */
node[rear[p]].next = -1;
} /* fin del for */

/* Copiar de regreso al archivo original */


for (i = 0; i < n; i++) {
x[i] = node[first].info;
first = node[first].next;
} /*fin del for */
} /* fin de radixsort*/

int main(void)
{
int x[50] = {NULL}, i;
static int n;

printf("\nCadena de n£meros enteros: \n");


for (n = 0;; n++)
if (!scanf("%d", &x[n])) break;
if (n)
radixsort (x, n);
for (i = 0; i < n; i++)
printf("%d ", x[i]);
return 0;
}

12. Ordenación por cajas

Utilizable cuando los datos a ordenar son valores discretos en un rango determinado •
p.e. números enteros en el rango 1...m Se crean m colas (una para cada posible valor del
campo llave) • se coloca cada elemento en su cola (o caja) correspondiente • se “vuelcan”
las cajas en el array original

método ordenaPorCajas(entero[0..n-1] t, entero m)

{valores de los elementos de t en el rango 1..m}

Cola[m] c

// inserta cada elemento en su caja

desde j:=0 hasta n-1 hacer

inserta(t[j],c[t[j]])

fhacer

// vuelca las cajas en el array

i := 0

desde k:=1 hasta m hacer

// mete cada elemento en la posición que le

// corresponde en el array ordenado

mientras c[k] no está vacía hacer

t[i] := extraePrimero(c[k])

i:=i+1

fhacer

fhacer

fmétodo
13. Ordenacion por cubetas

Ordenación de un array de objetos cuyas claves de ordenación son los n primeros


números enteros • m=n y no hay valores repetidos • no es necesario hacer cajas

método ordenaPorCubetas (Objeto[0..n-1] t)

desde i:=0 hasta n-1 hacer

mientras t[i].clave≠i hacer

intercambia t[i] con t[t[i]]

fhacer

fhacer

fmétodo

14. ordenamiento por cálculo de dirección

#include <stdio.h>
#include <conio.h>
#define N 8

main(void)
{
int x[N],f[10];
int i,j,p,a,s,y,first;
struct{
int info;
int next;
}node[N];
clrsc
r();

for(i=0;i<N;i++) /*lectura del arreglo x[N] a ordenar*/


{
printf("x[%d]=",i);
scanf("%d",&x[i]);
}

for(i=0;i<N-1;i++) /*Inicio de la lista disponible*/


node[i].next=i+; /*apun
tadores*/
node[N-1].next=-1;

for(i=0;i<N;i++) /*dato*/
node[i].info=x[i];
for(i=0;i<10;i++) /*Inicialización de apuntadores f[10]*/
f[i]=-1; /*al principio f[i] no apunta a na
da */

for(i=0;i<N;i++) /*Creación de sub-listas*/


{
y=x[i]; /*cálculo del digito de las decenas*/
first=y/10;
if(f[first]==-1) /*f[first] no apunta a nigún dato*/
{
f[firs
t]=i;
node[i].next=-1;
}
else /* f[first] apunta a un
dato*/
{
if(node[f[first]].next==-1) /*apunta al primer dato
en lista*/
{
if(node[f[first]].info < y)
{
node[f[first]].next=i;

node[i].next=-1;
}
else
{
node[i].next=f[first];
node[f[first]].next=-1;
f[first]=i;
}
}
else /*Se continua la
lista*/
{
a=f[first]; /*a= anterior*/
s=node[a].ne
xt; /*s= siguiente*/
if(y<node[f[first]].info)
{
f[first]=i;
node[i].next=a;
}
else
{
while(y>node[s].info&&s!=-1)
{
a=s;
s=node[s].next;
}
node[a].next=i;
/*i semejante a temp*/
node[i].next=s;
}
}
}
}
i=0; /*Copiar los números de
regreso*/
for(j=0;j<10;j++) /* al arreglo x[N] */
{
p=f[j];
while(p!=-1)

{
x[i++]=node[p].info;
p=node[p].next;
}
}
printf("\n");
for(i=0;i<N;i++)
printf("x[%d]=%d\n",i,x[i]);
getchar();
}