You are on page 1of 40

Diseo y Anlisis de Algoritmos.

(DAA-2009)

Dr. Eric Jeltsch F.

CAPITULO 5 - Algoritmos de Ordenamiento


Contenidos:
1. Algoritmos de Ordenacin (no lineal)y su anlisis.
2. HeapSort,
3. ShellSort,
4. QuickSort,
5. MergeSort,
6. StoogeSort y otros.
7. Estabilidad,
8. Algoritmos de Ordenacin (lineal)y su anlisis.
9. CountingSort, RadixSort, BucketSort.
Introduccin
En las aplicaciones informticas, existen dos clases generales de tcnicas de ordenamiento, ellas son
Internas y Externas. La ordenacin Interna se lleva a cabo en la memoria principal, lo que significa
que es utilizada la memoria de acceso directo de alta velocidad, mientras que la ordenacin Externa,
hace uso del almacenamiento secundario que es ms lento. Esta ltima tcnica se usa en general
para cuando se tiene una gran cantidad de datos, que hacen difcil el usar la memoria principal para
guardarlos. El problema en este sentido es el movimiento de datos que se genera entre la unidad
externa de almacenamiento y la memoria principal, generndose costos muy altos, pero no por
lentitud del algoritmo sino por la lentitud en la llamada y/o acceso de los datos que se usarn. Un
esquema general de los algoritmos de ordenamiento est dado por el siguiente diagrama, (existen
ms!!)

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Asumamos que nos dan una sucesin de n-elementos X[1], X[2], ... X[N], y que cada X[i], tiene
asociada una clave denotada por clave(X[i]). Se supone que existe una relacin de orden total sobre
las claves, esto significa que se cumple una de las siguientes posibilidades, ya sea:

clave(X[i]) < clave(X[j]),


clave(X[i]) = clave(X[j]),
clave(X[i])> clave(X[j]).

Adems se cumple la relacin de transitividad en la relacin de orden, es decir,


si clave(X[i])< clave(X[j]) y clave(X[j])< clave(X[k]) entonces clave(X[i])< clave(X[k]).
El problema de ordenar consiste entonces en reorganizar una coleccin de n-datos, de tal forma
que sus claves formen una sucesin no decreciente. Esto es, encontrar una ordenacin X[p(1],
X[p(2)] , ...,X[p(n)], de los n-elementos, tal que, clave(X[p(1)]) clave(X[p2]) clave(X[p(n)] ).
En el caso de algunos algoritmos, las comparaciones son un factor importante en el momento de
medir los costos, as como el nmero de intercambios que se realizan. En general, vamos a
considerar en este sentido que una cota inferior para el problema de ordenacin basado en
comparaciones viene dada por (nlogn), esto es, que en el peor caso, el tiempo de ejecucin del
mejor algoritmo de ordenacin basado en comparaciones debe realizar al menos nlogn operaciones.
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Existen mtodos directos de ordenacin, tales como por insercin que se refiere en insertar un
elemento dado en el lugar que le corresponde de una parte ya ordenada del array, por ejemplo,
InsertionSort, InsertionBinaria. Otra forma es a travs de la seleccin que consiste en seleccionar el
menor elemento de una parte desordenada del array y colocarlo en la posicin del primer elemento
no ordenado e intercambio que se refiere en comparar pares de elementos adyacentes e
intercambiarlos si estn desordenados, dentro de esta estrategia estn, por ejemplo, mtodo de la
burbuja o intercambio directo y el (ShakerSort) que es una variante del anterior. Existen otros
mtodos ms avanzados de clasificacin u ordenacin, ellos son: Insercin por incremento
decreciente (ShellSort), ordenacin por Heap (HeapSort) y clasificacin rpida o por particin
(QuickSort).
Una importante propiedad de algunos algoritmos de ordenacin es la estabilidad y se refiere a que el
orden relativo de los elementos con claves iguales permanece inalterado en el proceso de
clasificacin, es decir, no intercambia elementos con claves iguales.
Algunos algoritmos de ordenamiento agrupados segn estabilidad tomando en cuenta la
complejidad computacional.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Orden por Insercin (InsertionSort)


Dado un array A de n-elementos, la estrategia consiste en realizar n-recorridos por el array. En el
recorrido i-simo, el elemento almacenado en A[i-1] es trasladado a su lugar apropiado en A[0..i
-1]. De este modo, despus del recorrido i-simo, los elementos en A[0...i -1] estn en orden, lo que
significa que despus de n-recorridos, el array A completo estar ordenado.
Ejemplo: Lista Original, con entrada 4.1, 7.3, 1.7, 5.2 y 1.2.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Notar que despus de realizado el recorrido del array los datos estn ordenados.
INSERTION-SORT(A)
1 for j 2 to length[A]
2
do key A[j]
3
Insert A[j] into the sorted sequence A[1 .. j - 1].
4
i j - 1
5
while i > 0 and A[i] > key
6
do A[i + 1] A[i]
7
i i - 1
8
A[i + 1] key

Orden por Seleccin (SelectionSort)

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Dado un array A de n-elementos, la estrategia consiste en buscar el elemento ms pequeo, luego se


intercambia la posicin de ese elemento con la del elemento que est en la primera casilla, para
luego localizar el segundo elemento ms pequeo y su posicin se intercambia con el elemento que
est en la segunda casilla, si se prosigue de esta forma se consigue tener todos los elementos
ordenados. El nombre se relaciona con la seleccin del elemento que colocar.
Ejemplo: Lista Original, con entrada 4.1, 7.3, 1.7, 5.2 y 1.2.

INSERTION-SORT(A)
1 for j 2 to length[A]
2
do key A[j]
3
Insert A[j] into the sorted sequence A[1 .. j - 1]
4
i j - 1
5
while i > 0 and A[i] > key
6
do A[i + 1] A[i]
7
i i - 1
8
A[i + 1] key

Orden por Burbuja (BubbleSort)


Dado un array A de n-elementos, la estrategia consiste en comparar a travs de un recorrido por el
array las celdas contiguas, en donde las que no estn en orden, las intercambia. Cuando termina una
lectura de rastreo sin intercambiar elementos, se guardan los datos y el procedimiento puede
terminar. El nombre proviene del hecho que durante el primer ciclo el elemento ms grande
asciende hacia la parte superior, durante el segundo recorrido, el segundo elemento ms grande
asciende hasta su posicin, etc. El procedimiento continua hasta que todos los elementos quedan en
el que ser su ltimo lugar.
Ejemplo
Lista Original, con entrada 4.1, 7.3, 1.7, 5.2 y 1.2.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Notar que se necesitan 4 pasadas para que el array este finalmente ordenado.

BUBBLESORT(A)
1 for i 1 to length[A]
2
do for j length[A] downto i + 1
3
do if A[j] < A[j - 1]
4
then exchange A[j] A[j - 1]

Ordenacin por Incrementos (ShellSort)


Este mtodo se basa en la estrategia de ordenar por insercin de los elementos que difieren h 1posiciones, despus de los que difieren h2-posiciones, y as sucesivamente segn un conjunto de
incrementos decrecientes hi-posiciones, hasta ordenarlos que difieren en ht =1. Existen en este
sentido numerosos conjunto de incrementos decrecientes que garantizan la clasificacin del array,
como por ejemplo, 1, 2, 4...; 1, 3, 5, 9..; 1, 4, 13, 40, 121,...; Se comienza en cada caso por el
incremento mayor que permita el tamao del array y se va reduciendo en cada actuacin. El
ejemplo siguiente muestra un ordenacin ShellSort para un array de nueve elementos con
incrementos h1=4, h2=2 y h3 =1.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

En un primer paso se ordenan por insercin directa los elementos que estn separados 4 posiciones,
es as como deben ordenarse las claves de las posiciones 1, 5 y 9, con claves 8, 3 y 22
respectivamente; las posiciones 2 y 6 con claves 14 y 23; las posiciones 3 y 7 con claves 5 y 17; y
las posiciones 4 y 8 con claves 9 y 13, esta forma se conoce como clasificacin 4, de la misma
manera se acta con clasificacin 2 y 1 respectivamente.
/**
* Shellsort, usando una secuencia sugerida por Gonnet.
* a un array de claves int.
**/
shellsort(int[] a) {
for (int gap = a.length / 2; gap > 0;
gap = (gap == 2) ? 1 : (int) (gap / 2.2)) {
for (int i = gap; i < a.length; i++) {
int tmp = a[i];
int j = i;
for (; (j >= gap) && (tmp < a[j - gap]); j -= gap) {
a[j] = a[j - gap];
}
a[j] = tmp;
}

Ordenacin por Mezcla (MergeSort)


Dado un array A de n-elementos, por ejemplo A[0..n-1], la estrategia esta basada en la metodologa
Dividir para Conquistar, en donde el array es particionado en 2 subarrays, uno conteniendo n/2
-elementos y el otro conteniendo n/2 -elementos. En el caso que n sea potencia de 2, esta
subdivisin se reduce a n/2-elementos por cada subarray, sin entrar en conflicto con piso o techo,
notar que esta es la base de dividir). Estos subarrays son entonces ordenados invocando
recursivamente al algoritmo de ordenamiento Merge (mezcla, que es la fase vencer del algoritmo).
Finalmente los dos subarrays ya ordenados son combinados para producir el array ordenado final.
El algoritmo merge mezcla los dos arrays en un tercer array, en donde array1 y array2 estn ambos
ordenados en forma ascendente, array3.length = array1.length + array2.length.
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Tal como se adelantaba la operacin fundamental de este algoritmo es mezclar las dos listas
ordenadas. La idea bsica es tomar dos arrays de entrada A y B es orden, y la salida se entrega en el
array C. Vamos a considerar tres contadores, Actr, Bctr, y Cctr, para mostrar un ejemplo de cmo
trabaja. En todo caso, digamos que el ms pequeo de los A[Actr] y B[Bctr] es copiado en la
siguiente entrada en C (es decir, C[Cctr]), y el contador apropiado avanza. Cuando la lista de
entrada ha sido analizada, el resto de la otra lista es copiada a C.
Ejemplo: Veamos como trabaja para el array A: 1, 13, 24, 26, 2, 15, 27, 38.

MergeSort(A, p, r)
if p<r then
q= (p+r)/2
MergeSort(A, p, q)
MergeSort(A, q+1, r)
Merge(A, p, q, r)

En donde Merge esta dado por


MERGE(A, p, q, r)
1 n1 q - p + 1
2 n2 r - q
3 crea arrays L[1 .. n1 + 1] y R[1 .. n2 + 1]
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

4 for i 1 to n1
5
do L[i] A[p + i - 1]
6 for j 1 to n2
7
do R[j] A[q + j]
8 L[n1 + 1]
9 R[n2 + 1]
10 i 1
11 j 1
12 for k p to r
13
do if L[i] R[j]
14
then A[k] L[i]
15
i i + 1
16
else A[k] R[j]
17
j j + 1

Para ordenar una sucesin de entrada A=(A(1), A(2)...A(n)) se debe llamar a MergeSort(A, 1,
length[A]), donde length[A] = n.
Ejecucin de MergeSort() recursivo, visualizando las diversas particiones que se realizan.

Ahora se muestra una traza en trmino de las llamadas al procedimiento MergeSort y Merge, para el
array A: 55, 22, 44, 66, 11, 33, 22, 66.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

rbol de Recursin MERGE-SORT para un arreglo de 16 elementos.


Considerando A=[a1,a2,,a16]

Orden Rpido (Quicksort)


Dado un array A de n-elementos, la estrategia tambin esta basada en la metodologa Dividir para
Conquistar. Sin embargo, a diferencia del algoritmo de ordenacin por mezcla, la parte no recursiva
del algoritmo de ordenacin rpida conlleva la construccin de subejemplares por medio de una
tcnica de particin, en vez de combinar las soluciones parciales mediante mezcla. Especficamente,
la ordenacin rpida divide A en dos subarrays que pueden ser ordenados de forma independiente.
Se selecciona un elemento especifico del array A[p] llamado pivote, seguidamente se recorre el
array desde la izquierda hasta encontrar una llave mayor que el pivote, y desde la derecha hasta
encontrar una menor, una vez ocurrido se intercambian, el proceso se repite hasta que los ndices de
incremento y decremento se cruzan. En esta situacin notar que, el array est dividido en dos partes,
la izquierda con todos los elementos menores que el pivote y la derecha con todos los mayores. A
cada una de estas partes se le llama particin, se repite luego el mtodo para cada una de las
particiones y as sucesivamente hasta que no haya particiones a ordenar.
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Una muestra de ordenacin por particin para un arrays de 9 elementos, se puede ver a
continuacin, en donde estn los detalles para la obtencin de la primera particin. Dada la entrada
de 7-elementos
Ejemplo.
Dada la lista o array 5 - 3 - 7 - 6 - 2 - 1 - 4. Comenzamos con la lista completa. El elemento divisor
o pivote es 4:
5-3-7-6-2-1-4
Comparamos con el 5 por la izquierda y el 1 por la derecha.
5-3-7-6-2-1-4
5 es mayor que cuatro y 1 es menor. Intercambiamos:
1-3-7-6-2-5-4
Avanzamos por la izquierda y la derecha:
1-3-7-6-2-5-4
3 es menor que 4: avanzamos por la izquierda. 2 es menor que 4: nos mantenemos ah.
1-3-7-6-2-5-4
7 es mayor que 4 y 2 es menor: intercambiamos.
1-3-2-6-7-5-4
Avanzamos por ambos lados:
1-3-2-6-7-5-4
En este momento termina el ciclo principal, porque los ndices se cruzaron. Ahora intercambiamos
con el pivote, quedando
1-3-2-4-7-5-6
Aplicando en forma recursiva el proceso pero a la sub-lista de la izquierda (ndices 0 - 2). Tenemos
lo siguiente:
1-3-2
1 es menor que 2: avanzamos por la izquierda. 3 es mayor: avanzamos por la derecha. Como se
intercambiaron los ndices termina el ciclo. Se intercambia
1-2-3
Para resumir la segunda sub-lista, se tiene
7-5-6
5-7-6
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

5-6-7
Para cada nueva sub-lista se retorna sin hacer cambios (se cruzan los ndices).
Finalmente, al retornar de la primera llamada se tiene el arreglo ordenado:
1 - 2 - 3 - 4 - 5 - 6 7.
Sea el array A[p..r], donde p es el primer ndice y r el ltimo del array.
QUICKSORT(A, p, r)
1 if p < r
2 then q PARTITION(A, p, r)
3 QUICKSORT(A, p, q - 1)
4 QUICKSORT(A, q + 1, r)

Luego para ordenar el array A, la llamada inicial es QUICKSORT(A,1,length[A]), siendo length[a]


el largo del arreglo A. Como ya mencionamos el procedimiento PARTITION(A, p, r) es el ms
importante y que es en definitiva el procedimiento que particiona en segmentos el array, para luego
realizar las llamadas recursivas a QUICKSORT(A, p, r) nuevamente pero en subarrays.
PARTITION(A, p, r)
1 x A[r]
2 i p - 1
3 for j p to r - 1
4
do if A[j] x
5
then i i + 1
6
exchange A[i] A[j]
7 exchange A[i + 1] A[r]
8 return i + 1

Ejemplo:
En este caso, se pretende mostrar como se logra la primera particin del array, para luego realizarlo
en forma recursiva. Consideremos el array

el pivote se indicar con un asterisco(*) y con un crculo(O) los elementos que se deben
intercambiar para obtener las sucesivas particiones.
Veamos en detalle como se obtiene la primera particin.

se comienza inicializando los ndices i y j a la primera y ltima posicin del array (elementos 3 y
22). A continuacin, se comienza a incrementar el ndice del inicio(i) hasta que se encuentre un
elemento que no sea menor que el pivote, lo que se consigue al llegar al segundo elemento(14).
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

una vez localizado un elemento mayor o igual, se ir el ndice de final(j) decrementando hasta
encontrar un elemento que sea menor(o igual) que el pivote(5). Se intercambian estos dos elementos
y se avanzan ambos ndices (se incrementa i y se decrementa j).

Ahora se sigue con el mismo proceso, es decir, se comienza a incrementar i hasta localizar un
elemento no menor que el pivote y despus se decrementa j hasta localizar uno no mayor, se
intercambian y se avanzan los dos ndices.

Se contina el proceso realizando todos los intercambios necesarios hasta que ambos ndices se
crucen.

En este momento tenemos en la parte inferior del array los elementos menores o igual al pivote y en
la otra los mayores.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

A continuacin, se procede de la misma manera con cada una de las particiones, en la primera el
pivote ser el 5 y en la segunda ser 23. Esto da lugar a nuevas particiones hasta que al final todas
las particiones quedan de tamao 1 con lo que el array queda ordenado. En efecto,

Otra forma de representarlo para el array, con la mitad como pivote.


_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)


24

17

66

43

21

Dr. Eric Jeltsch F.


5

91

14

18

Ejemplo
Con este ejemplo para A = (55, 22, 44, 66, 11, 33, 22, 66) deseo mostrar la relevancia de las
llamadas al procedimiento recursivo QuickSort() con su procedimiento Partition().

Comienza fase de dividir, similar a lo realizado anteriormente, llegando a obtener la sucesin


ordenada, tal como se muestra a continuacin,

La traza en trmino de las llamadas al procedimiento QuickSort() y Partition(), es la siguiente:

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Para obtener finalmente:

11

22

Dr. Eric Jeltsch F.

33 33

44

55

66 77

Otro ejemplo, un array con valores


X [1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

[10] [11] [12]

38

25

46

17

60

22

33

76

72

12

95

85

Por lo antes descrito se puede visualizar lo siguiente:


X

[1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

[10]

[11]

[12]

38

25

46

17

60

22

33

76

72

12

95

85

X [1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

[10]

[11]

[12]

12

25

46

17

60

22

33

76

72

38

95

85

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

X [1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

[10]

[11]

[12]

12

25

38

17

60

22

33

76

72

46

95

85

J
X [1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

[10]

[11]

[12]

12

25

33

17

60

22

38

76

72

46

95

85

X [1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

[10]

[11]

[12]

12

25

33

17

38

22

60

76

72

46

95

85

Las posiciones 7 y 12 marcan la 2 seccin. Bajo el principio antes sealado podemos continuar
escogiendo el pivote y realizando lo mismo de antes pero para estas secciones en forma
independiente despus de realizada las particiones respectivas.
1.

Seccin

[1]

[2]

[3]

[4]

[5]

[1]

[2]

[3]

12

25

33

17

22

25

33

17

22

33

17

25

22

25

17

22

17

25

33

2.

[4]
22

33

Seccin

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

[1]

[2]

[3]

[4]

[5]

[6]

[1]

[2]

[3]

[4]

[5]

[6]

60

76

72

46

95

85

46

76

72

60

95

85

46

60

72

76

95

72

76

95

85

85

Otra observacin interesante es analizar el nmero de comparaciones en la situacin que el array


este ordenado, resultando ser la ms alta, originndose as, el peor caso. Por ejemplo, para el array
ordenado y eligiendo el pivote como el primer elemento de la izquierda en cada particin, se tiene:

12

25

33

37

48

57

86

92

7-comparaciones
12

25

33

37

48

57

86

92

12

25

33

37

48

57

86

92

12

25

33

37

48

57

86

92

12

25

33

37

48

57

86

92

12

25

33

37

48

57

86

92

12

25

33

37

48

57

12

25

33

37

48

57

6-comparaciones

5-comparaciones

4-comparaciones

3-comparaciones

2-comparaciones
86

92

1-comparacin
86

92

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Se puede verificar que son necesarias 28-comparaciones, en general se necesitan [ (n -1) + (n -2) +
(n -3) + ....+ 1] - comparaciones, para una entrada de n-elementos, lo que hace que sea proporcional
a n2. Existen en todo caso un gran nmero de estrategias con el fin de mejorar la eleccin del pivote.
Anlisis Informal:
PARTITION realiza (n) comparaciones (donde n = r - p + 1).
Caso peor: para cuando el array esta ordenado, dada una particin no balanceada:
T(n) = (n) + T(n-1) + T(1), lo que implica T(n) = (n2).
Caso mejor: particiones ideales, cada vez:
T(n) = (n) + 2T(n/2), lo que implica T(n) = (n lgn).
Caso promedio: probablemente (nlgn), ya que an con malas particiones (digamos 99-1),
se tiene T(n) = (n) + T( 99n /100 ) + T( n/100) , lo que implica T(n) = (n lg n).
Una primera sugerencia sera hacer uso de un nmero aleatorio para elegir el elemento de divisin,
pero el costo relacionado con la generacin de nmeros seudo-aleatorios podra ser prohibitivo, otra
estrategia muy exitosa es la estrategia de las medianas, que consiste en escoger el pivote de entre 3
elementos, datos[inf], datos[mitad] y datos[sup], especficamente el algoritmo selecciona la
mediana de estos tres elementos con base en el valor de la clave, permitiendo as asegurar que el
elemento de divisin no est ubicado en ninguno de los extremos del array. Existen otras variante,
como la mediana de cinco que trabaja en forma similar. Ahora desde el punto de vista performance (
o rendimiento) es posible usar el algoritmo de Insercin (InsertionSort) en los subarray que se
obtienen, pero cuando son suficientemente pequeos.
Ejemplo:
Se muestra a continuacin una demo de quick sort con median-of-three partitioning. Su tarea si
desea emprenderla es generar otras formas de particionar y compararlas en tiempo, n de
comparaciones o de llamadas a los procedimientos si son recursivos.
class ArrayIns
{
private long[] elArray;
// referencia al array elArray
private int nElems;
// numero de elementos
//-------------------------------------------------------------public ArrayIns(int max)
// constructor
{
elArray = new long[max];
// crea el array
nElems = 0;
// no hay elementos
}
//-------------------------------------------------------------public void insert(long valor)
// put elemento al array
{
elArray[nElems] = valor;
// insertarlo
nElems++;
// incrementa el tamao
}
//-------------------------------------------------------------public void display()
// displays el contenido del array
{
System.out.print("A=");
for(int j=0; j<nElems; j++)
// para todos los elementos,
System.out.print(elArray[j] + " "); // display
System.out.println("");
}
//-------------------------------------------------------------public void quickSort()
{
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

recQuickSort(0, nElems-1);
}
//-------------------------------------------------------------public void recQuickSort(int izq, int der)
{
int tam = der-izq+1;
if(tam <= 3)
// orden manual si el tam es pequeo
manualSort(izq, der);
else
// quicksort si es grande
{
long mediana = medianDe3(izq, der);
int particion = particionIt(izq, der, mediana);
recQuickSort(izq, particion-1);
recQuickSort(particion+1, der);
}
} // end recQuickSort()
//-------------------------------------------------------------public long medianDe3(int izq, int der)
{
int centro = (izq+der)/2;
// ordena izq & centro
if( elArray[izq] > elArray[centro] )
swap(izq, centro);
// ordena izq & der
if( elArray[izq] > elArray[der] )
swap(izq, der);
// ordena centro & der
if( elArray[centro] > elArray[der] )
swap(centro, der);
swap(centro, der-1);
// put el pivot a la der
return elArray[der-1];
// return valor mediana
} // end medianDe3()
//-------------------------------------------------------------public void swap(int dex1, int dex2) // swap 2 elementos
{
long temp = elArray[dex1];
// A en temp
elArray[dex1] = elArray[dex2];
// B en A
elArray[dex2] = temp;
// temp en B
} // end swap(
//-------------------------------------------------------------public int particionIt(int izq, int der, long pivote)
{
int izqPtr = izq;
// der del primer elemento
int derPtr = der - 1;
// izq de pivote
while(true)
{
while( elArray[++izqPtr] < pivote ) // hallar el ms grande
;
//
(nop)
while( elArray[--derPtr] > pivote ) // hallar el ms pequeo
;
//
(nop)
if(izqPtr >= derPtr)
// si los punteros se cruzan,
break;
//
particion no se realiza
else
// no se cruzan
swap(izqPtr, derPtr); // swap los elementos
} // end while(true)
swap(izqPtr, der-1);
// restaura el pivote
return izqPtr;
// return lugar del pivote
} // end partitionIt()
//-------------------------------------------------------------_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

public void manualSort(int izq, int der)


{
int tam = der-izq+1;
if(tam <= 1)
return;
if(tam == 2)
{
if( elArray[izq] > elArray[der] )
swap(izq, der);
return;
}
else
// tam es 3
{
// 3-sort izq, centro & der
if( elArray[izq] > elArray[der-1] )
swap(izq, der-1);
// izq, centro
if( elArray[izq] > elArray[der] )
swap(izq, der);
// izq, der
if( elArray[der-1] > elArray[der] )
swap(der-1, der);
// centro, der
}
} // end manualSort()
//-------------------------------------------------------------} // end class ArrayIns
class quickSort_mediana
{
public static void main(String[] args)
{
int maxTam = 16;
// tamao array
ArrayIns arr;
// referencia al array
arr = new ArrayIns(maxTam); // crea el array

for(int j=0; j<maxTam; j++) // completer el array


{
// con n random
long n = (int)(java.lang.Math.random()*99);
arr.insert(n);
}
arr.display();
// display los elementos
arr.quickSort();
//los ordena
arr.display();
// display los elementos luego de ordenarlos
} // end main()
// end class quickSort_mediana

Otra aplicacin interesante del algoritmo de ordenamiento QuickSort es el clculo del k-simo
mayor elemento de una lista de datos, pues permite adems de ordenar un array, calcular en forma
eficaz el k-simo elemento mayor del mismo. Observar que calcular la mediana consiste en calcular
el k-simo elemento mayor, con k = n/2. El k-simo mayor elemento de un vector es aquel elemento
que, tras ordenar el vector, ocupa la posicin nmero k.
Por ejemplo, para averiguar el sexto mayor (3- mayor) elemento del vector:
v = (2, 3, 6, 8, 3, 4, 1, 5, 3, 5, 6, 1) lo ordenamos:
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

v = (1, 1, 2, 3, 3, 3, 4, 5, 5, 6, 6, 8) y vemos que en la sexta posicin aparece el 3.


Ordenando en Java
Finalmente, se presentan algunos ejemplos ms prcticos, desde el punto de vista de la asignatura
en el sentido de comparar estos dos ltimos algoritmos de ordenamiento recursivo que son
QuickSort y MergeSort. En todo caso este tipo de actividades sern abordadas en los laboratorios,
usando datos de distinta ndoles a ordenar (por ejemplo integers, float, strings, cadenas de string, u
Objetos en general, desde o hacia a un archivo, etc.), haciendo uso de interfaces apropiadas como
Comparable y libreras tales como Collections y las genricas de Java ( Generics), segn sea el
caso. Este primer programa compara QuickSort con MergeSort, tomando un conjunto de datos. Por
ejemplo: 1000; 2000; 5000; 10000.
class Comparando_QuickMergeSort {
static void quickSort(int A[], int p, int r)
{
if (p < r)
{
int q = partition(A,p,r);
quickSort(A, p, q);
quickSort(A, q+1, r);
}
}
static void mergeSort(int A[], int B[], int p, int r)
{
if (p < r)
{
int q = (p+r)/2;
mergeSort(A, B, p, q);
mergeSort(A, B, q+1, r);
merge(A,B,p,q,r);
}
}
static int partition(int A[], int p, int r)
{
int x = A[p];
int i = p-1;
int j = r+1;
while (true)
{
do j--;
while (A[j] > x);
do i++;
while (A[i] < x);
if (i < j)
{
int tmp = A[i];
A[i] = A[j];
A[j] = tmp;
}
else return j;
}
}
static void merge(int A[], int B[], int p, int q, int r)
{
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

int i = p;
int j = q+1;
int k = 0;
while ( i <= q && j <= r )
if (A[i] < A[j])
B[k++] = A[i++];
else B[k++] = A[j++];
while ( i <= q )
B[k++] = A[i++];
while ( j <= r )
B[k++] = A[j++];
for (i=0; i < k; i++)
A[p+i] = B[i];

static void printArray(String text, int A[])


{
System.out.print(text);
System.out.print(" es: ");
for (int i = 0; i < A.length; i++)
System.out.print(A[i]+ " ");
System.out.println();
}
public static void main (String args[]) {
for (int j = 0; j < 4; j++)
{
long t;
int tam = 0;
switch
{
case
case
case
case
}

(j)
0
1
2
3

:
:
:
:

tam
tam
tam
tam

=
=
=
=

1000; break;
2000; break;
5000; break;
10000; break;

int A[] = new int[tam];


int B[] = new int[tam];
for (int i = A.length-1; i >= 0; i--)
A[i] = B[i] = (int)( tam * Math.random());
t = System.currentTimeMillis();
quickSort(A,0,A.length-1);
t = System.currentTimeMillis()-t;
System.out.print("quickSort " + tam );
System.out.println(" items toma tiempo = "+t);
t = System.currentTimeMillis();
int C[] = new int[A.length];
mergeSort(B,C,0,B.length-1);
t = System.currentTimeMillis()-t;
System.out.print("mergeSort " + tam);
System.out.println(" items toma tiempo = "+t);
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

}
}

Este otro programa usa las herramientas y mtodos de la librera Collection de Java para ordenar, en
donde la librera Java utiliza una variante de QuickSort
import java.util.*;
public class CollectionsSortDemo
{
public static void main(String args[])
{
String feld[] =
{ "Regina","Angela","Michaela","Maria","Josepha",
"Amalia","Vera","Valentina","Daniela","Saida", "Linda","Elisa" };
List l = Arrays.asList(feld);
Collections.sort(l);
System.out.println(l);
}
}

Este otro programa ordena datos de diferente ndole a travs de una Interface propia que
implementa el mtodo menorQue(), en la clase Algoritmos.java ( la que se debe encontrar en el
directorio en donde se ejecute la aplicacin Ejemplo_Ordenable.java
public class Algoritmos {
public static void ordenar(Ordenable a[ ]) {
Ordenable temp;
int este;
for (int i=0; i<a.length-1; i++) {
este = i;
for (int j=i+1; j<a.length; j++)
if (a[j].menorQue(a[este])) este = j;
temp=a[este];
a[este]=a[i];
a[i]=temp;
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)


}

Dr. Eric Jeltsch F.

}
import java.util.*;
public class Ejemplo_Ordenable {
public static void main(String args[]) {
Pais[]paises={new Pais("Brasil"),new Pais("Argentina"),new Pais("Chile")};
Entero[] numeros={new Entero(3),new Entero(4), new Entero(1)};
Algoritmos.ordenar(paises);
Algoritmos.ordenar(numeros);
for (int i=0; i<paises.length; i++)
System.out.println(paises[i]);
for (int i=0; i<numeros.length; i++)
System.out.println(numeros[i]);
}

El orden en Java
Recordar que la Interface Comparable del paquete java.lang sirve entre otras cosas para
determinar el orden natural de los objetos.
/**************** Comparable.java *****************************
public interface Comparable
{
public int compareTo(Comparable a);
}

Desde la versin JDK 1.2 es la Interface Comparable lista para ser usada en diversas clases, tales
como String, Character, Double, etc. Sin embrago, existen otra tambin muy til, llamada Interface
Comparator .
/**************** Comparator.java *****************************
public interface Comparator
{
public int compare(Object element1, Object element2);
public boolean equals(Object o);
}

Observar que lo sustantivo de esta asignatura es mostrar la performance de los algortitmos de


ordenamiento. Sin embargo, en este otro ejemplo se muestra una aplicacin del problema de
ordenamiento y la programacin orientada a objetos, con el fin de ordenar las personas por apellido
usando InsertionSort, con el fin de generar un todo con la asignatura de programacin orientada a
objetos y la de diseo y anlisis de algoritmos. Se pueden hacer las variantes necesarias con el fin
de ordenar por edad o por nombre, segn sea el caso.
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

class Persona
{
private String apellido;
private String nombre;
private int edad;
//----------------------------------------------------------public Persona(String apell, String nom, int e)
{
// constructor
apellido = apell;
nombre = nom;
edad = e;
}
//----------------------------------------------------------public void displayPersona()
{
System.out.print("
Apellido : " + apellido);
System.out.print(", Nombre : " + nombre);
System.out.println(", Edad : " + edad);
}
//----------------------------------------------------------public String getApellido()
// obtener el apellido
{ return apellido; }
} // end class Persona
class ArrayConObj
{
private Persona[] a;
// refa al array a
private int nElems;
// numero de datos
//-------------------------------------------------------------public ArrayConObj(int max)
// constructor
{
a = new Persona[max];
// crea el array
nElems = 0;
// no existe por ahora
}
//-------------------------------------------------------------// put persona en el array
public void insert(String apell, String nom, int e)
{
a[nElems] = new Persona(apell, nom, e);
nElems++;
// incrementa el tamao
}
//-------------------------------------------------------------public void display()
// displays el contenido del array
{
for(int j=0; j<nElems; j++)
// para todos,
a[j].displayPersona();
// los display
}
//-------------------------------------------------------------public void insertionSort()
{
int in, out;
for(out=1; out<nElems; out++)
{
Persona temp = a[out];
in = out;
while(in>0 &&
a[in-1].getApellido().compareTo(temp.getApellido())>0)
{
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

}
}

Dr. Eric Jeltsch F.

a[in] = a[in-1];
--in;
}
a[in] = temp;
} // end for
// end insertionSort()

// end class ArrayConObj

class OrdenandoObjetos
{
public static void main(String[] args)
{
int maxTam = 100;
ArrayConObj arr;
arr = new ArrayConObj(maxTam);
arr.insert("Evans", "Patty", 24);
arr.insert("Lopez", "Manuel", 59);
arr.insert("Salgado", "Laura", 37);
arr.insert("Smith", "Pablo", 37);
arr.insert("Yaez", "Tomas", 43);
arr.insert("Hashinomas", "Sato", 21);
arr.insert("Salco", "Brand", 29);
arr.insert("Velasquez", "Jose", 72);
arr.insert("Vega", "Manuel", 22);
arr.insert("Cresler", "Lucinda", 18);

System.out.println("Antes de Ordenar:");
arr.display();
arr.insertionSort();
System.out.println("Despues de Ordenar:");
arr.display();
} // end main()
// end class OrdenandoObjetos

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Este es otro ejemplo, el cual usa mtodo generics que usa wildcards para ordenar una lista en
orden ascendente. Bsicamente, todos los elementos en la lista deben ser implementados por la
interfaceComparable. http://java.sun.com/developer/technicalArticles/J2SE/generics/
publicstatic<TextendsComparable<?superT>>voidsort(List<T>list){
Objecta[]=list.toArray();
Arrays.sort(a);
ListIterator<T>i=list.listIterator();
for(intj=0;j<a.length;j++){
i.index();
i.set((T)a[j]);
}
}

http://www.dafi.upv.es/examenes/ad3_f97.pdf
Orden mediante Heap (Heapsort)
Dado un array A de n-elementos, la estrategia puede ser recursiva o iterativa, en cualquier caso este
mtodo se basa en la estructura de datos Heap. Recordemos que un Heap es un rbol binario
completo con informacin perteneciente a un conjunto ordenado. Los Heap tienen la caracterstica
de que cada nodo padre tiene un valor mayor que el de todos sus nodos hijos.
Un rbol cumple la condicin de Heap si satisface dicha condicin y adems es un rbol binario
completo. Un rbol binario es completo cuando todos los niveles estn llenos (ledos de izquierda a
derecha), con las excepcin del ltimo que puede quedar exento de dicho cumplimiento.
sta es la nica restriccin en los Heap. Ello implica que el mayor elemento (o el menor,
dependiendo de la relacin de orden escogida) est siempre en el nodo raz. Debido a esto, los heap
se utilizan para implementar colas de prioridad, por la razn de que en una cola siempre se consulta
el elemento de mayor valor, y esto conlleva la ventaja de que en los Heap dicho elemento est en la
raz. Otra ventaja que poseen los Heap es que su implementacin usando arrays es muy eficaz, por
la sencillez de su codificacin y liberacin de memoria, ya que no hace falta utilizar punteros. No
slo existen Heap ordenados con el elemento de la raz mayor que el de sus hijos, sino tambin que
la raz sea menor que sus progenitores. Todo depende de la ordenacin con la que nos interese
programar el Heap. La eficiencia de las operaciones en los Heap es crucial en diversos algoritmos
de recorrido de grafos y de ordenamiento HeapSort.
En un array A que representa un heap es un objeto con dos atributos: length[A], que es el n de
elementos en el array, y heap-size[A], que es el n de elementos en el heap almacenado dentro del
array A. En esta figura se muestra un max_heap, visto como un Heap (a) y como un array (b).

Resulta muy simple el verificar las frmulas siguientes


PARENT(i), siendo i el ndice del Array y no los valores A(i), return i/2. Por ejemplo el Parent(8)
corresponde a 8/2= 4. As mismo, LEFT(i) return 2i y RIGHT(i) return 2i + 1. A continuacin
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

se muestra MAX-HEAPIFY como una importante subroutine para manipular max-heaps. La


entrada es un array A y el index i del mismo, tal como se muestra

MAX-HEAPIFY(A, i)
1 l LEFT(i)
2 r RIGHT(i)
3 if l heap-size[A] and A[l] > A[i]
4 then largest l
5 else largest i
6 if r heap-size[A] and A[r] > A[largest]
7 then largest r
8 if largest i
9 then exchange A[i] A[largest]
10 MAX-HEAPIFY(A, largest)

A continuacin se ve la accin de este procedimiento sobre el Array A, antes dado.

La figura anterior muestra la accin de MAX-HEAPIFY(A, 2), donde heap-size[A] = 10. (a) La
configuracin inicial con A[2], en donde i = 2 viola la propiedad de max-heap ya que no es ms
grande que sus hijos. Luego en (b) se restaura la max-heap property para el nodo 2 intercambiendo

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

A[2] con A[4], la que vuelve a generar un problema, ahora con el nodo 4. Las llamadas recursivas a
MAXHEAPIFY(A, 4) con i = 4. Intercambia A[4] con A[9], se muestra en (c), nodo 4 ya restaurado.
Existe en todo caso toda una metodologa para transformar un rbol binario completo en un Heap.
BUILD-MAX-HEAP(A)
1 heap-size[A] length[A]
2 for i length[A]/2 downto 1
3 do MAX-HEAPIFY(A, i)

La figura anterior, muestra la operacin de BUILD-MAX-HEAP, mostrando la estructura de dato


antes de la llamada a MAX-HEAPIFY en lnea 3 de BUILD-MAX-HEAP. (a) Los 10-elementos de
entrada del array A y su rbol binario. La figura muestra que el loop index i referido al nodo 5 antes
de la llamada a MAX-HEAPIFY(A, i). (b) Muestra la estructura resultante. El loop index i para la
siguiente iteracin referida al nodo 4. (c)-(e) Subsecuencia de iteraciones del for loop en BUILDMAXHEAP. Observe que MAX-HEAPIFY es llamado sobre un nodo, los dos subrboles de ese
nodo son ambos max-heaps. (f) El max-heap despus de terminado BUILD-MAX-HEAP. El
mtodo de ordenamiento que usa la estructura Heap es presentado en el libro [CLR, CLRS],
llamado HeapSort, el que trabaja eliminando los elementos ms pequeo del heap, hasta que queda
vaco, para luego almacenar los mismos elementos eliminados en el mismo array.
HEAPSORT(A)
1 BUILD-MAX-HEAP(A)
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)


2
3
4
5

Dr. Eric Jeltsch F.

for i length[A] downto 2


do exchange A[1] A[i]
heap-size[A] heap-size[A] - 1
MAX-HEAPIFY(A, 1)

El algoritmo HeapSort parte usando Build-Heap para construir un heap sobre la entrada de datos
dada en A[1 .. n], donde n = length[A]. La figura siguiente muestra un ejemplo de la operacin de
HeapSort antes que el heap este inicialmente construido. La operacin de HeapSort() considera en
la etapa (a) la estructura de dato heap justamente despus de que haya sido construido por BuidHeap(), las etapas (b)-(j) son las etapas despus de las llamadas de Heapify en la lnea 5. El valor de
i es mostrado cada vez. La etapa (k) es el array ordenado resultante.

El concepto de heap se puede extender a una nueva estructura, llamada treap la cual es un binary
search tree con respecto a los elementos del nodo y un heap con respecto a las prioridades de los
nodos. De all el nombre, "treap" = "tree heap". En todo caso esta estructura la volveremos a ver
para cuando veamos rboles y sus rotaciones.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Ordenar en tiempo lineal.


Qu tan rpido es posible ordenar ?. Hasta ahora sabemos que diferentes algoritmos requieren un
tiempo de O(n log n) para ordenar n-elementos. La mayora de ellos comparan los elementos
adyacentes realizando los intercambios correspondientes, entre ellos MergeSort, HeapSort y
QuickSort son asintticamente optimales, realizando nlog(n) comparaciones. Sin embargo, existen
otros algoritmos an ms rpido pero no trabajan basado en comparaciones, sino que van ordenando
respecto del dgito correspondiente.
Ordenacin mediante direcciones (RadixSort)
Dado un array A de n-elementos, en el cual cada elemento tiene d-dgitos, donde el dgito 1 es de
menor prioridad respecto del dgito d, que tiene la ms alta, la idea es ir ordenando los elementos
dgito a dgito, comenzando de izquierda a derecha, en cada pasada podr determinar que las
columnas de los dgitos se encuentran ordenadas, hasta que se ordene la primera columna que
corresponden al primer dgito de los nmeros que toma parte en el array. Notar que se realizan
tantas pasadas como dgitos tengan los elementos del array, observar que si usa algoritmos estables
como intermediario podr optimizar los resultados de ordenacin.
RadixSort(A, d)
for i=1 to d do
// Use un algoritmo de ordenacin estable
// para ordenar A sobre un dgito i.

A continuacin vemos un ejemplo de cmo trabaja RadixSort, el cual hace una primera pasada, en
orden por el 3er dgito, desde izquierda a derecha, anlogamente por el segundo dgito y finalmente
por el primer dgito. Tal como se muestra a continuacin. La flecha indica la posicin del dgito que
ser ordenado, el procedimiento asume que todos los elementos en el array A tienen d-dgitos.

Sin embargo, es factible obtener un peor caso. Por ejemplo, dado un arreglo de 10 elementos de 4
dgitos cada uno con los que Radix-Sort alcanza su peor comportamiento cuando se usa
InsertionSort para ordenar cada dgito, 0909 1818 2727 3636 4545 5454 6363 7272
8181
9090. En efecto, si se ejecuta Radix-Sort sobre esta secuencia de nmeros usando
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

InsertionSort para ordenar cada dgito, al ordenar el dgito menos significativo se alcanza el peor
comportamiento ya que estos se encuentran ordenados de mayor a menor. Despus de ordenar el
dgito menos significativo, el conjunto de los segundos dgitos significativos quedan ordenados de
mayor a menor generando nuevamente el peor comportamiento para InsertionSort, lo mismo pasa
con los siguientes dos dgitos. Es interesante entonces el considerar casos mejor, peor y promedio.
Algunos resultados interesante

Dado n n de d-dgitos en el cual todo dgito puede tomar k valores posibles, RADIXSORT
ordena correctamente estos n en tiempo (d(n + k)).

Ejemplo:
Probar que n enteros en el rango de 1 a n2 se pueden ordenar en tiempo O(n). En efecto, el nmero
de dgitos utilizado para representar n2 nmeros diferentes en un sistema de nmeros k-ario es:
logk(n2). Entonces, considerando los n2 nmeros como nmeros en radix-n, tenemos que d = logn(n2)
= 2 logn(n) = 2. Por lo tanto, necesitamos 2 dgitos, es decir, d = 2. Por otro lado, cada dgito
requiere n smbolos (radix-n), por lo que k = n. Entonces T(n) = (d(n + k)) = (2(n + n)) = (n).
Para cuando d es constante y k = O(n), radix sort corre en tiempo lineal.

Dado n n de b-bit y cualquier n entero r b, RADIX-SORT ordena correctamente estos


n en tiempo ((b/r)(n + 2r)).

Notar que si escogemos r = log(n) implica que T(n,b) = (bn/log(n)). De donde para n en el rango
de 0 a nd 1, se tiene que b = d log(n), de donde radixSort corre en tiempo = (dn).
Ordenacin mediante direcciones (BucketSort)
En BucketSort, la entrada A1, A2, , AN debe consistir solamente de enteros positivos menores que
M. El algoritmo toma un array llamado en esta oportunidad B, de tamao M, el cual es inicializado
a 0s. Luego, B tiene M celdas, o buckets, las que estn inicialmente vaca. Mientras Ai es ledo se
va incrementando B[i] en 1, segn la frecuencia de las claves. Despus que toda la entrada haya sido
leda, se escanea el array B, imprimiendo una representacin de la lista ordenada. Un ejemplo se
muestra a continuacin sobre un array de 8 elementos, los cuales son: 3, 6, 4, 1, 3, 4, 1, 4

Examinando el array de entrada e incrementando los correspondientes bucket o casilleros de B, se


obtiene

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

A partir de este ltimo resultado vamos a imprimir la lista en forma ordenada.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Ordenacin mediante direcciones (CountingSort)


Dado un array A de n-elementos, en el cual los elementos que lo componen son enteros en el rango
de 1 a k, para algn entero k. La idea bsica es determinar, para cada elemento x el nmero de
elementos menores que x, la cual puede ser usada para localizar el elemento x directamente en su
posicin en el array de salida, es decir si por ejemplo se tienen 17 elementos menores que x,
entonces x pertenece o est en la posicin 18 de la salida.
Counting sort:
Todos los elementos son enteros, no existen comparaciones entre los elementos.
Input: A[1 . . n], donde A[ j] {1, 2, , k}, Output: B[1 . . n], ordenado, siendo C[1 . . k] un arreglo
auxiliar.
COUNTING-SORT(A, B, k)
1 for i 0 to k
2
do C[i] 0
3 for j 1 to length[A]
4
do C[A[j]] C[A[j]] + 1
5 C[i] ahora contiene el n de elementos iguales a i.
6 for i 1 to k
7
do C[i] C[i] + C[i - 1]
8 C[i] ahora contiene el n de elementos que son menores o iguales a i.
9 for j length[A] downto 1
10
do B[C[A[j]]] A[j]
11
C[A[j]] C[A[j]] 1

LOOP 1

LOOP 2
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

LOOP 3

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

LOOP 4

En resumen se tiene,

Notar que Counting sort es un algoritmo estable.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

Se puede verificar que este algoritmo es estable en general, lo que significa que puede ser usado
para aplicarlo en el ordenamiento RadixSort. No obstante, existen ciertos parmetros sobre el
tiempo de ejecucin de los algoritmos que hemos vistos y que funcionan a travs de comparaciones,
es decir, no se considera el resultado siguiente para los algoritmos RadixSort, CountingSort y
BucketSort
Teorema
Cualquier algoritmo de ordenamiento que funcione a travs de comparaciones requiere (n lg n)
comparaciones en el caso peor.
Para justificar lo anterior, consideremos los rboles de decisin que ayudan a aclarar esta
afirmacin. A continuacin se muestra un rbol de decisin en donde todo nodo interno es rotulado
i : j para i, j {1, 2,, n}. El subrbol izquierdo muestra las secuencias de comparaciones, ai aj.
El subrbol derecho muestra la secuencia de comparaciones ai aj.

Como se puede observar toda hoja contiene una permutacin p(1), p(2),, p(n), para indicar que el
orden ap(1) ap(2) ap(3) ap(4) .. ap(n) , ha sido establecido. (es decir, p(1) = a2 , p(2) = a3,
p(3) = a1 ).
Con este argumento se puede afirmar que un rbol de decisin puede modelar la ejecucin de
cualquier algoritmo de ordenamiento basado en comparaciones. Adems podemos concluir que,
_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

Diseo y Anlisis de Algoritmos. (DAA-2009)

Dr. Eric Jeltsch F.

se obtiene un rbol para cada entrada de tamao n,


el tiempo de ejecucin del algoritmo es igual al largo del camino.
el tiempo caso peor corresponde a la altura del rbol.

A continuacin, se muestran algunos criterios generales a tomar en cuenta para escoger de mejor
manera (dada una aplicacin) el mejor algoritmo de ordenamiento.
Recordar que cada algoritmo su mrito propio y se comportan de modo diferente de acuerdo a la
cantidad y la forma en que se le presenten los datos, entre otras cosas. No existe EL algoritmo de
ordenamiento que nos sirva siempre, slo existe el mejor para cada caso particular. Debe conocer a
fondo el problema que quiere resolver, y aplicar el ms adecuado. Aunque hay algunas preguntas
que te pueden ayudar a elegir:
1. Qu grado de orden tendr la informacin que va a manejar? Si la informacin va a estar
casi ordenada y no quiere complicarse, un algoritmo sencillo como el ordenamiento burbuja
ser suficiente. Si por el contrario los datos van a estar muy desordenados, un algoritmo
poderoso como Quicksort puede ser el ms indicado. Y si no puede hacer una presuncin sobre
el grado de orden de la informacin, lo mejor ser elegir un algoritmo que se comporte de
manera similar en cualquiera de estos dos casos extremos.
2. Qu cantidad de datos va a manipular? Si la cantidad es pequea, no es necesario utilizar un
algoritmo complejo, y es preferible uno de fcil implementacin. Una cantidad muy grande
puede hacer prohibitivo utilizar un algoritmo que requiera de mucha memoria adicional.
3. Qu tipo de datos quiere ordenar? Algunos algoritmos slo funcionan con un tipo especfico
de datos (enteros, enteros positivos, etc.) y otros son generales, es decir, aplicables a cualquier
tipo de dato.
4. Qu tamao tienen los registros de su lista? Algunos algoritmos realizan mltiples
intercambios (burbuja, insercin). Si los registros son de gran tamao estos intercambios son
ms lentos.
5. Requerimientos de memoria: El algoritmo puede necesitar memoria adicional para realizar su
labor. En general es preferible que no sea as, pero es comn en la programacin tener que
sacrificar memoria por rendimiento.

_____________________________________________________________________________Escuela de
Ingeniera en Computacin, Universidad de La Serena.

You might also like