Vous êtes sur la page 1sur 21

2.

Algoritmos de Ordenamiento
Contenido
2.1. Insertion Sort
2.2. Selection Sort
2.3. Shell Sort
2.4. Bubble Sort
2.5. Merge Sort
2.6. Heap Sort
2.7. Partition-Exchange Sort o Quicksort
2.8. Radix Sort
2.9. Address-Calculation Sort

Debido a que las estructuras de datos son utilizadas para almacenar información,
para poder recuperar esa información de manera eficiente es deseable que
aquella esté ordenada. Existen varios métodos para ordenar las diferentes
estructuras de datos básicas.

En general los métodos de ordenamiento no son utilizados con frecuencia, en


algunos casos sólo una vez. Hay métodos muy simples de implementar que son
útiles en los casos en dónde el número de elementos a ordenar no es muy grande
(ej, menos de 500 elementos). Por otro lado hay métodos sofisticados, más
difíciles de implementar pero que son más eficientes en cuestión de tiempo de
ejecución.

Los métodos sencillos por lo general requieren de aproximadamente n x n pasos


para ordenar n elementos.

Los métodos simples son: insertion sort (o por inserción directa) selection sort,
bubble sort, y shellsort, en dónde el último es una extensón al insertion sort,
siendo más rápido. Los métodos más complejos son el quick-sort, el heap sort,
radix y address-calculation sort. El ordenar un grupo de datos significa mover los
datos o sus referencias para que queden en una secuencia tal que represente un
orden, el cual puede ser numérico, alfabético o incluso alfanumérico, ascendente o
descendente.

Se ha dicho que el ordenamiento puede efectuarse moviendo los registros con las
claves. El mover un registro completo implica un costo, el cual se incrementa
conforme sea mayor el tamaño del registro. Es por ello que es deseable evitar al
máximo el movimiento de los registros. Una alternativa es el crear una tabla de
referencias a los registros y mover las referencias y no los datos. A continuación
se mostrarán los métodos de ordenamiento empezando por el más sencillo y
avanzando hacia los mas sofisticados
La eficiencia de los algoritmos se mide por el número de comparaciones e
intercambios que tienen que hacer, es decir, se toma n como el número de
elementos que tiene el arreglo a ordenar y se dice que un algoritmo realiza O(n 2)
comparaciones cuando compara n veces los n elementos, n x n = n2.

Análisis de Algoritmos Notación de Orden

Una función f(n) se define de orden O(g(n)), es decir, f(n) = O(g(n)) si existen
constantes positivas n0 y c tales que:

| f(n) | = c * <= | g(n) | , para toda n > n0

100 n3 => O(n3)

6n2 + 2n + 4 => O(n2)

1024 => O(1)

1+2+3+4+...+n-1+n= n * (n+1)/2 = O(n2)

2.1. Insertion Sort

Este es uno de los métodos más sencillos. Consta de tomar uno por uno los
elementos de un arreglo y recorrerlo hacia su posición con respecto a los
anteriormente ordenados. Así empieza con el segundo elemento y lo ordena con
respecto al primero. Luego sigue con el tercero y lo coloca en su posición
ordenada con respecto a los dos anteriores, así sucesivamente hasta recorrer
todas las posiciones del arreglo. Este es el algoritmo:

Procedimiento Insertion Sort

Este procedimiento recibe el arreglo de datos a ordenar a[] y altera las posiciones
de sus elementos hasta dejarlos ordenados de menor a mayor. N representa el
número de elementos que contiene a[].

paso 1: [Para cada pos. del arreglo] For i = 2 to N do


paso 2: [Inicializa v y j] v = a[i]
j = i.
paso 3: [Compara v con los anteriores] While a[j-1] > v AND j>1 do
paso 4: [Recorre los datos mayores] Set a[j] = a[j-1],
paso 5: [Decrementa j] set j = j-1.
paso 5: [Inserta v en su posición] Set a[j] = v
paso 6: [Fin] End.

Ejemplo:

Si el arreglo a ordenar es a = ['a','s','o','r','t','i','n','g','e','x','a','m','p','l','e'],


el algoritmo va a recorrer el arreglo de izquierda a derecha. Primero toma el
segundo dato 's' y lo asigna a v y i toma el valor de la posición actual de v.

Luego compara esta 's' con lo que hay en la posición j-1, es decir, con 'a'. Debido
a que 's' no es menor que 'a' no sucede nada y avanza i.

Ahora v toma el valor 'o' y lo compara con 's', como es menor recorre a la 's' a la
posición de la 'o'; decrementa j, la cual ahora tiene la posición en dónde estaba la
's'; compara a 'o' con a[j-1] , es decir, con 'a'. Como no es menor que la 'a' sale del
for y pone la 'o' en la posición a[j]. El resultado hasta este punto es el arreglo
siguiente: a = ['a','o','s','r',....]

Así se continúa y el resultado final es el arreglo ordenado :

a = ['a','a','e','e','g','i','l','m','n','o','p','r','s','t','x']

2.2. Selection Sort

El método de ordenamiento por selección consiste en encontrar el menor de todos


los elementos del arreglo e intercambiarlo con el que está en la primera posición.
Luego el segundo más pequeño, y así sucesivamente hasta ordenar todo el
arreglo.

Procedimiento Selection Sort

paso 1: [Para cada pos. del arreglo] For i = 1 to N do


paso 2: [Inicializa la pos. del menor] menor = i
paso 3: [Recorre todo el arreglo] For j = i+1 to N do
paso 4: [Si a[j] es menor] If a[j] < a[menor] then
paso 5: [Reasigna el apuntador al menor] min = j
paso 6: [Intercambia los datos de la pos. min y posición i] Swap(a, min, j).
paso 7: [Fin] End.

Ejemplo:

El arreglo a ordenar es a = ['a','s','o','r','t','i','n','g','e','x','a','m','p','l','e']. Se empieza


por recorrer el arreglo hasta encontrar el menor elemento. En este caso el menor
elemento es la primera 'a'. De manera que no ocurre ningún cambio. Luego se
procede a buscar el siguiente elemento y se encuentra la segunda 'a'. Esta se
intercambia con el dato que está en la segunta posición, la 's', quedando el arreglo
así después de dos recorridos: a = ['a','a','o','r','t','i','n','g','e','x','s','m','p','l','e'].
El siguiente elemento, el tercero en orden de menor mayor es la primera 'e', la cual
se intercambia con lo que está en la tercera posición, o sea, la 'o'. Le sigue la
segunda 's', la cual es intercambiada con la 'r'. El arreglo ahora se ve de la
siguiente manera: a = ['a','a','e','e','t','i','n','g','o','x','s','m','p','l','r']. De esta manera se
va buscando el elemento que debe ir en la siguiente posición hasta ordenar todo el
arreglo.

El número de comparaciones que realiza este algoritmo es:

 para el primer elemento se comparan n-1 datos, en general para el


elemento i-ésimo se hacen n-i comparaciones, por lo tanto, el total de
comparaciones es:
 la sumatoria para i de 1 a n-1 (n-i) = 1/2 n (n-1).

2.3. Shellsort

Denominado así por su desarrollador Donald Shell (1959), ordena una estructura
de una manera similar a la del Bubble Sort, sin embargo no ordena elementos
adyacentes sino que utiliza una segmentación entre los datos. Esta segmentación
puede ser de cualquier tamaño de acuerdo a una secuencia de valores que
empiezan con un valor grande (pero menor al tamaño total de la estructura) y van
disminuyendo hasta llegar al '1'. Una secuencia que se ha comprobado ser de las
mejores es: ...1093, 364, 121, 40, 13, 4, 1. En contraste, una secuencia que es
mala porque no produce un ordenamiento muy eficiente es ...64, 32, 16, 8, 4, 2, 1.

Su complejidad es de O(n1.2) en el mejor caso y de O(n1.25) en el caso promedio.

void shellsort ( int a[], int n)


/* Este procedimiento recibe un arreglo a ordenar a[] y el tamaño del arreglo n. Utiliza en este caso
una serie de t=6 incrementos h=[1,4,13,40,121,364] para el proceso (asumimos que el arreglo no
es muy grande). */
{
int x,i,j,inc,s;

for(s=1; s < t; s++) /* recorre el arreglo de incrementos */


{
inc = h[s];
for(i=inc+1; i < n; i++)
{
x = a[i];
j = i-inc;
while( j > 0 && a[j] > x)
{
a[j+h] = a[j];
j = j-h;
}
a[j+h] = x;
}
}
}

2.4. Bubble Sort

El bubble sort, también conocido como ordenamiento burbuja, funciona de la


siguiente manera: Se recorre el arreglo intercambiando los elementos adjacentes
que estén desordenados. Se recorre el arreglo tantas veces hasta que ya no haya
cambios. Prácticamente lo que hace es tomar el elemento mayor y lo va
recorriendo de posición en posición hasta ponerlo en su lugar.

Procedimiento Bubble Sort

paso 1: [Inicializa i al final de arreglo] For i = N downto 1 do


paso 2: [Inicia desde la segunda pos.] For j = 2 to i do
paso 4: [Si a[j-1] es mayor que el que le sigue] If a[j-1] < a[j] then
paso 5: [Los intercambia] Swap(a, j-1, j).
paso 7: [Fin] End.

Tiempo de ejecución del bubble sort:

 para el mejor caso (un paso) O(n)


 peor caso n(n-1)/2
 promedio O(n2)

2.5. 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.

Procedimiento MergeSort

/*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}

2.6. 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 ecencialmente 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.

Procedimiento Heapsort

/* Recibe como parámetros un arreglo a ordenar y un entero que indica el número de datos 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 á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;
}

2.7. Partition-Exchange Sort o Quicksort

Es un método de ordenamiento recursivo y en lenguajes en dónde no se permite


la recursividad esto puede causar un retraso significativo en la ejecución del
quicksort.

Su tiempo de ejecución es de n log2n en promedio.

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


{
int i,j,v;
if(r > l)
{
v = a[r];
i = l-1;
j = r;
for(;;)
{
while(a[++i] < v && i < r);
while(a[--j] > v && j > l);
if( i >= j)
break;
swap(a,i,j);
}
swap(a,i,r);
quicksort(a,l,i-1);
quicksort(a,i+1,r);
}
}

a = {a,s,o,r,t,i,n}

aiortsn

ainrtso

ainotsr

ainorst

2.8. Radix Sort


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.

Por ejemplo el número 235 se escribe 2 en la posición de centenas, un 3 en la


posición de decenas y un 5 en la posición de unidades.

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).

Este mismo principio se toma para Radix Sort, para visualizar esto mejor tenemos
el siguiente ejemplo. En el ejemplo anterior se ordeno de izquierda a derecha.
Ahora vamos a ordenar de derecha a izquierda.

Archivo original.
25 57 48 37 12 92 86 33

Asignamos colas basadas en el dígito menos significativo.

Parte delantera Parte posterior

2 12 92

3 33

5 25

6 86

7 57 37

8 48

10

Después de la primera pasada:

12 92 33 25 86 57 37 48

Colas basadas en el dígito más significativo.

Parte delantera Parte posterior

1 12

2 25

3 33 37

4 48

5 57
6

8 86

9 92

10

Archivo ordenado: 12 25 33 37 48 57 86 92

ASORTINGEXAMPLE

AEOLMINGEAXTPRS

AEAEGINMLO

AAEEG

AA

AA

EEG

EE

INMLO

LMNO

LM

NO

STPRX

SRPT

PRS

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

Estado de la lista

i Node[i].info Node[i].next

Inicialización K = 1 K = 2 K =
3
0 65 1 3 1 2
1 789 2 -1 -1 -1
2 123 3 0 3 3
3 457 -1 1 0 1

rear = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}

2031

front = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
2031

k=1

p=0p=1p=2p=3

first = 1 first = 2 first = 3 first = -1

y = 65 y = 789 y = 123 y = 457

exp = 1 exp = 1 exp = 1 exp = 1

j=5j=9j=3j=7

q = -1 q = -1 q = -1 q = -1

si q == -1 si q == -1 si q == -1 si q == -1

front[5] = 0 front[9] = 1 front[3] = 2 front[7] = 3

rear[5] = 0 rear[9] = 1 rear[3] = 2 rear[7] = 3

j=3

first = 2

while ( j <= 9)

i=5

si i <= 9

p=5

node[2].next = 0

j=5

i=7

si i <= 9

p=7

node[0].next = 3

j=5

i=9

si i <= 9
p=9

node[2].next = 1

j=9

fin del while

p=9

node[1].next = -1

Características.

Debido a que el ciclo for (k = 1; k <= m; k++) externo se recorre m veces (una para
cada dígito) y el ciclo interior n veces (una para cada elemento en el archivo) el
ordenamiento es de aproximadamente (m*n).

Si las llaves son complejas (es decir, si casi cada número que puede ser una llave
lo es en realidad) m se aproxima a log n, por lo que (m*n) se aproxima a (n log n).

Si la cantidad de dígitos es grande, en ocasiones es más eficiente ordenar el


archivo aplicando primero el ordenamiento de raíz a los dígitos más significativos y
después utilizando inserción directa sobre el archivo ordenado.

Ventajas.

El ordenamiento es razonablemente eficiente si el número de dígitos en las llaves


no es demasiado grande.

Si las máquinas tienen la ventaja de ordenar los dígitos (sobre todo si están en
binario) lo ejecutarían con mucho mayor rapidez de lo que ejecutan una
comparación de dos llaves completas.

2.9. Address-Calculation Sort

Ordenamiento por cálculo de dirección


En este método, se aplica una función f a cada llave. El resultado de esta función
determina dentro de cuál entre varios archivos se va a colocar el registro. La
función debe tener la propiedad de qie si x<=y,f(x),<=f(y). Esta función se
denomina preservadora de orden .Por tanto, todos lo registros en un subarchivo
tendrán llaves que sean menores que o iguales a las llaves de los registros en
otros subarchivos. Un elemento se coloca en un subarchivo en secuencia correcta
utilizando cualquier método de ordenamiento; con frecencia se utiliza la inserción
simple. Después de que se han colocado todos los elementos del archivo original
en subarchivos se concatenan para producir el resultado ordenado.

Por ejemplo, consideremos el archivo de muestra.

25 57 48 37 12 92 86 33

Vamos a crear 10 subarchivos,uno para cada uno de los 10 primeros dígitos


posibles. Al principio , cada uno de estos subarchivos está vacío. Se declara un
arreglo de apuntadores f[10], en donde f[i] apunta al primer elemento en el archivo
cuyo dígito es i. Después de examinar el primer elemento (25), se coloca en el
archiv o encabezado por f[2]. Cada uno de los subarchivos se conserva como una
lista ligada ordenada de los elementos de arreglo originales. Después de procesar
cada uno de los elementos en el archivo original, aparecen los subarchivos como
se muestra a continuación.
Algoritmo de ordenamiento.

Presentamos una rutina para implementar el ordenamiento de cálculo de dirección.


La rutina supone un arreglo de números de 2 dígitos y utiliza el primer dígito de
cada número para asignar cada número a un subarchivo.
#define N... /* N es el número de elementos a ordenar*/

addr( int x[],int n)


{
int f[10],first,i,j,p,y;

struct{
int info;
int next;
} node[N]

/* Inicializar la lista ligada disponible */


for(i=0;i<n-1;i++)
node[i].next=i+1;
node[n-1].next=-1;

for(i=0;i<n;i++)
node[i].info=x[i];

/* Inicializar los apuntadores */


for(i=0;i<10;i++)
f[i]=-1;

for(i=0;i<n;i++)
{ /* Insertamos sucesivamente cada elemento en su */
/* subarchivo respectivo utilizando inserción de lista */
y=x[i];
first=y/10; /* Encontrar el dígito de las decenas */
/* Buscar en la lista ligada */
place(&f[first],y);
/* place inserta "y" en su posición correcta en la lista */
/* a la que se apunta mediante f[first] */
}

/* Copiar los números de regreso al erreglo x */


i=0;
for(j=0;j<10;j++)
{
p=f[j];
while(p!=-1)
{
x[i++]=node[p].info;
p=node[p].next;

}
}
}

Programa de ordemaniento 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+; /*apuntadores*/
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 nada */

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[first]=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].next; /*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();
}

Los requisitos de espacio del ordenamiento de calculo de dirección son


aproximadamente 2*n (utilizado mediante el arreglo node) más algunos nodos de
encabezado y variables temporales. Observe que si los datos originales se
proporcionan en la forma de una lista ligada y no como un arreglo secuencia l, no
es necesario conservar el arreglo x y la estructura vinculada node.

Para evaluar los requisitos de tiempo para el ordenamiento considere lo siguiente:


si la distribución aproximada de los n elementos originales está uniform emnete
distribuida por los m subarchivos y el valor de n/m es aproximadamente 1, el
tiempo de ordenamiento es casi O(n),dado que la función asigna cada elemento a
su propio archivo y se requiere poco trabajo adicional para colocar el elemento
dentro del subarchivo mismo. Por otra parte, si n/m es mucho más grande que 1, o
si el archivo original no está uniformemente distribuido por los m subarchivos, se
requiere bastante trabajo para insertar un elemento en su propio subarchivo.

Vous aimerez peut-être aussi