Beruflich Dokumente
Kultur Dokumente
Métodos de Ordenamiento
Arturo Díaz Pérez
Tipos de Ordenamiento
F Ordenamiento interno.
ß Se lleva a cabo completamente en memoria principal. Todos los
objetos que se ordenan caben en la memoria principal de la
computadora
F Ordenamiento externo.
ß No cabe toda la información en memoria principal y es necesario
ocupar memoria secundaria. El ordenamiento ocurre
transfiriendo bloques de información a memoria principal en
donde se ordena el bloque y este es regresado, ya ordenado, a
memoria secundaria
Formulación
Criterios de Eficiencia
F Criterios de eficiencia
ß El número de pasos
ß Método de Burbujeo
ß Método de Inserción
ß Método de Selección
Método de Burbujeo
25 3 12 19 2 1 9 6
1 25 3 12 19 2 6 9
void Burbujeo( int A[], int n)
2 25 3 12 19 6 9 {
int i,j;
3 25 6 12 19 9 for( i=0; i < n-1; i++ )
for( j=n-1; j > i; j--)
6 25 9 12 19 if( A[j] < A[j-1] )
Intercambia( &A[j], &A[j-1] );
9 25 12 19
}
12 25 19
19 25
Método de Burbujeo
void Burbujeo( int A[], int n)
{
int i,j;
for( i=0; i < n-1; i++ )
for( j=n-1; j > i; j--)
if( A[j] < A[j-1] )
Intercambia( &A[j], &A[j-1] );
}
n −1 n −1
n(n − 1) n 2 n
Comparaciones: c = ∑ (n − i ) = ∑ i = = −
i =1 i =1 2 2 2
Movimientos: M min = 0
n −1 n −1
n(n − 1) n 2 n
M max = ∑ ( n − i ) = ∑ i = = −
i =1 i =1 2 2 2
Método de Selección
25 3 12 19 2 1 9 6
1 3 12 19 2 25 9 6 void Selección( int A[], int n )
{
2 12 19 3 25 9 6 int i, j, imin;
for( i=0; i < n-1; i++ ) {
3 19 12 25 9 6 imin = i;
for( j = i+1; j > n; j++ )
6 12 25 9 19 if( A[j] < A[imin] )
9 25 12 19 imin = j;
intercambia( &A[i], &A[imin] );
12 25 19 }
}
19 25
Método de Selección
void Selección( int A[], int n )
{
int i, j, imin;
for( i=0; i < n-1; i++ ) {
imin = i;
for( j = i+1; j > n; j++ )
if( A[j] < A[imin] )
imin = j;
intercambia( &A[i], &A[imin] );
}
}
n−1 n−1
n(n − 1) n2 n
Comparaciones: C = ∑n − i = ∑i = = −
i=1 i =1 2 2 2
Movimientos:
M = n −1
Método de Inserción
Método de Inserción
void Inserción( int A[], int n )
{
int i,j;
Comparaciones: Cmin = n − 1
n −1 n −1
n( n − 1) n 2 n
Cmax = ∑ ( n − i ) = ∑ i = = −
i =1 i =1 2 2 2
Movimientos: M min = 0
n −1
n ( n − 1) n 2 n
M max = ∑ i = = −
i =1 2 2 2
Análisis y Diseño de Algoritmos Sorting-11
QuickSort
F Dado un arreglo desordenado de n elementos
1 2 3 n-1 n
A
1 2 j-1 j n
v
< v >v
QuickSort
1 2 n
1 2 j-1 j n
v
< v >v
void quicksort( int A[], int i, int j )
{
if( desde A[i] hasta A[j] existen al
menos dos llaves distintas ) {
Seleccionar un pivote, v
Permutar A[i], ...,A[j], tal que,
para algún k entre i+1 y j,
A[i], ..., A[k-1] < v y
A[k], . . . , A[j] ≥ v
quicksort( A, i, k-1 );
quicksort( A, k, j );
}
}
Análisis y Diseño de Algoritmos Sorting-13
QuickSort: Pivote
i j
QuickSort: Particionamiento
i j
A[p] <v, i ≤ p <l
A[p] ≥ v, r <p ≤ j
<v >v
l r
int particion( int A[],int i, int j,
int v )
.
.
{
int l,r;
l=i; r=j;
do {
Intercambia( A[l], A[r] )
while( comp( A[l], v ) < 0 ) El tiempo de ejecución de
l++; partición es O(j-i+1)
while( comp( A[r], v ) >= 0 )
r--;
} while ( l<r );
return l;
}
QuickSort: Particionamiento
QuickSort: Ejemplo
Pivote 25 25 3 12 6 2 3 9 6
Pivote 6 6 3 12 6 2 3 9 25
Pivote 3 3 3 2 6 12 9 6 Pivote 12
2 3 3 6 6 9 12
Pivote 9
6 6 9
rn
rn-1
r1 r2
• El tiempo tomado por quicksort para este caso es la suma sobre todos los
elementos del número de veces que el elemento forma parte de un subarreglo
en el cual se hace un llamado a quicksort.
rn-1 3
n(n + 1)
= n+ −1
2
n 2 3n
r1 n = + −1
2r 2 2
F Por lo tanto,
2 n −1
T ( n) ≤ ∑ T (i) + c2 n
n − 1 i =1
2 n −1
≤ ∑ ci log i + c2n
n − 1 i =1
2c 2
n
n −1
T ( n) ≤ ∑ i log i + ∑ i log i + c2 n
n − 1 i =1 i = n2 +1
2c 2
n
n −1
≤ ∑ i (log n − 1) + ∑ i log n + c2 n
n − 1 i =1 i = 2 +1
n
2c n n nn 3 n
≤ + 1 log n − + 1 + n − 1 log n + c2 n
n − 1 4 2 42 4 2
Análisis y Diseño de Algoritmos Sorting-27
2c n 2 n n 2 n
≤ − log n − + + c2 n
n − 1 2 2 8 4
2c n(n − 1) n 2 + 2n
≤ log n − + c2 n
n −1 2 8
cn cn
≤ cn log n − − + c2 n
4 2( n − 1)
F Si c ≥ 4c2, entonces, la suma del segundo y cuarto
término no es mayor que 0,
F Ya que el tercer término es una contribución negativa,
entonces T(n) ≤ cnlog2n.
Análisis y Diseño de Algoritmos Sorting-28
HeapSort
F Estructura de datos abstracta
ß AGREGA, BORRAMIN, VACIA e INICIA
5 4
9 1 3 6
3 7 9 2 8
Análisis y Diseño de Algoritmos Sorting-30
HeapSort, cont.
9 5 4 9 1 3 6 3 7 9 2 8
1 2 3 4 5 6 7 8 9 10 11 12
5 4
9 1 3 6
3 7 9 2 8
F Nota:
ß Si n es el número de elementos del arreglo, n/2 son nodos
interiores del árbol binario.
F Sólo los nodos interiores se deben considerar para
ordenar el árbol en forma parcial.
HeapSort: Descenso.
F Supongamos que los elementos
A[i], . . . ,A[j]
HeapSort: Descenso.
void desciende( int A, int i, int j )
{
int r;
r = i;
while( r <= j/2) {
if( 2*r+1 > j ) { /* r tiene sólo un hijo */
if( comp( A[r], A[2*r]) > 0 )
intercambia ( &A[r], &A[2*r] );
r = j;
} else { /* r tiene dos hijos */
if( comp( A[r], A[2*r] ) > 0 &&
comp( A[2*r], A[2*r+1] ) <= 0 ) {
intercambia( &A[r], &A[2*r] );
r = 2*r;
} else if( comp( A[r], A[2*r+1] ) > 0 &&
comp( A[2*r+1], A[2*r] ) <= 0 ) {
intercambia( &A[r], &A[2*r+1] );
r = 2*r+1;
} else
/* no se viola la propiedad de los árboles
parcialmente ordenados */
r = j;
}
}
Análisis y Diseño de Algoritmos Sorting-33
HeapSort, cont.
A[1] A[n-k] A[n-k+1] A[n]
Ordenamiento Lineal
Ordenamiento Lineal
F Se puede usar otra forma para ordenar el arreglo A con llaves
1, ..., n usando el mismo arreglo en tiempo O(n).
ß Se visitan A[1], . . . , A[n] en ese orden.
/Si el registro A[i] tiene una llave j ≠ i, se intercambia con A[j].
/Si después del intercambio, el elemento que está ahora en A[i]
tiene llave k ≠ i, se intercambia A[i] con A[k], y se sigue así hasta
que en A[i] quede el registro con llave i.
ß Cada intercambio coloca algún registro en su lugar y una vez ahí nunca
se mueva más.
Análisis y Diseño de Algoritmos Sorting-36
Ordenamiento Lineal
Si se permiten llaves duplicadas, entonces, para cada valor llave, k,
debe existir una lista, L[k], de todos los elementos con la llave k.
1
2
k rp rq
Ordenamiento Lineal
#define MAX_LLAVE . . .
typedef . . . LISTA
BinSort: Inserta
Operación de Inserción
inicio
fin
BinSort: Concatena
Operación de Concatenación
BinSort
F Observaciones:
ß Suponga que se desea ordenar una lista de valores enteros en el
rango 0 a n2-1. Se utilizan n cubetas, una para cada uno de los
enteros 0,1, . . . ,n-1
ß Dos fases:
/Se coloca el entero i al final de la cubeta i mod n
/Se seleccionan los valores en el orden en que están
almacenados en las cubetas desde la 0 hasta la n-1. El entero i
se coloca al final de la cubeta i/n
BinSort: Ejemplo
F Ejemplo
ß 0, 1, 81, 64, 4, 25, 36, 16, 9, 49
BinSort
F Observaciones:
ß Si los números i, j están en el rango 0 a n2-1 se puede pensar que
ellos se pueden expresar en base n como números de dos dígitos,
esto es,
/i = an + b y j = cn + d, donde a, b, c, y d están dentro del
rango 0,n-1
/Si i < j, entonces, a ≤ c
3 Si a < c, i aparece en una cubeta menor a la de j en la segunda
pasada, así que i precederá a j en el ordenamiento final.
3 Si a = c, entonces, b <d.
» En la primera pasada i debe preceder a j, i en b y j en d.
» En la segunda pasada i y j son colocados en la misma
cubeta, i antes que j
RadixSort
F Suponga que se desea ordenar una lista de elementos cuyos
valores llave consisten de k componentes, f1, f2, . . . , fk, cuyos
tipos son t1, t2, ..., tk.
F Orden lexicográfico
ß (a1, a2, ..., ak) es menor que (b1, b2, ..., bk), si sucede solo una de las
condiciones siguientes:
• a1 < b1
• a1 = b1 y a2 < b2
• ...
• a1 = b1, a2 = b2, ..., ak-1 = bk-1 y ak < bk
/Así, para algún j entre 0 y k-1, a1 = b1, ..., aj = bj y aj+1 < bj+1.
RadixSort
F La idea clave detrás del método es ordenar todos los elementos
de acuerdo al campo fk (el dígito menos significativo ) y luego
concatenar las cubetas.
ß Después aplicar el método para fk-1 y así hasta f1.
RadixSort
void RadixSort()
/* Ordena la lista A de n elementos con llaves que
consisten de los campos f1, f2, ..., fk de tipos
t1, t2, . . . , tk, respectivamente. Utiliza arreglos
Bi, 1 ≤ i ≤ k, para las cubetas de los valores en el
campo fi */
{
RadixSort
void RadixSort()
{
(1) for( i = k; i >= 1; i-- ) {
(2) for( cada valor v del tipo ti )
(3) INICIA( Bi[v] );
∑ O( s i + n) ⇒ O( kn + ∑ si ) ú O( n + ∑ si )
i =1 i =1 i =1
Análisis y Diseño de Algoritmos Sorting-47
Arboles de Decisión
F Un árbol de decisión para un método de ordenamiento
es un árbol binario en el cual sus nodos representan el
estado del método después de hacer algún número de
comparaciones.
Arboles de Decisión
Arboles de Decisión
Fsi se ordena una lista de elementos de tamaño n, a1, a2, ..., an existen n! =
n(n-1) (n-2) (2) (1) posibles ordenamientos correctos.
FLa longitud del camino más largo de la raíz a una hoja es una cota inferior
en el número de pasos ejecutados por el algoritmo en el peor caso.
FYa que un árbol binario con k hojas debe tener un camino de longitud al
menos log k, entonces, un algoritmo de ordenamiento que utiliza sólo
comparaciones para ordenar una lista de n elementos debe tomar en el peor
caso un tiempo Ω( log n! ). n
n n n n 2
n!= n ⋅ ( n − 1) ⋅ ... ⋅ (2) ⋅ (1) ≥ ⋅ ⋅ ... ⋅ =
2 2 2 2
n/2 veces
n n n n
log( n!) ≥ log = log n −
2 2 2 2
Análisis y Diseño de Algoritmos Sorting-50
Arboles de Decisión
FEl ordenamiento por comparaciones requiere un tiempo Ω( n logn ) en el
peor caso