Está en la página 1de 33

Análisis y Diseño de Algoritmos

Ordenamiento – Heapsort y Quicksort

Diseño de Algoritmos Ordenamiento – Heapsort y Quicksort DR. JESÚS A. GONZÁLEZ BERNAL CIENCIAS COMPUTACIONALES INAOE

DR. JESÚS A. GONZÁLEZ BERNAL CIENCIAS COMPUTACIONALES INAOE

Heaps 2 2 —   Un Heap es una estructura de datos binaria ¡  
Heaps
2
2
—   Un Heap es una estructura de datos binaria
¡   Un arreglo que representa un árbol binario completo

Heaps

3 3
3 3

— Cada nodo es un elemento del arreglo

¡ Almacena el valor en el nodo ¡ Árbol completamente lleno, excepto en el último nivel (tal vez)

— Arreglo representando el heap

¡ 2 atributos

÷ Length[A] à # elementos en el arreglo A ÷ Heap-size[A] à # elementos en el heap almacenados en arreglo A

¡ Heap-size length[A] ¡ Raíz del árbol A[1]

Heaps

4 4
4
4

— Dado el índice i de un nodo

¡ Parent(i) à return floor(i/2) ¡ Left(i) à return 2i ¡ Right(i) à return (2i + 1)

— Propiedad Heap

¡ MAX-HEAP: A[PARENT(i)] A[i] ¡ MIN-HEAP: A[PARENT(i)] A[i]

— Altura de un nodo

¡ # arcos de la ruta simple más larga del nodo a una hoja

— Altura del árbol

¡ Altura de la raíz ¡ Altura del árbol es Θ (lgn)

Heaps

5 5
5
5

— Manipulación de heaps

¡ Entrada

÷ Arreglo A y un índice i ÷ Asume que LEFT(i) y RIGHT(i) son heaps ¢ A[i] puede ser menor que sus hijos

Viola la propiedad de un heap (MAX-HEAP)

¡ Heapify

÷ Mueve A[i] en el heap ¢ El subárbol con raíz en el índice i se convierte en un heap

Heapify 6 —   Algoritmo Heapify ¡   Llamada recursiva a Heapify para sus i’s
Heapify
6
—   Algoritmo Heapify
¡   Llamada recursiva a Heapify para sus i’s subárboles, si no
cumplen con la propiedad del heap

Heapify

7 7
7 7

— Heap-size[A] à 10 — A[2], i = 2 no cumple con la propiedad de un heap (MAX-HEAP)

Heapify 7 7 —   Heap-size[A] à 10 —   A[2], i = 2 no cumple
Heapify 8
Heapify
8

Heapify

9 9
9 9

— Tiempo de ejecución de heapify

¡ En un subárbol de tamaño n, con raíz en el nodo i

÷ Θ (1), relación fija entre A[i], A[LEFT(i)], A[RIGHT(i)] más ÷ Tiempo de ejecución de HEAPIFY en un subárbol con raíz en uno de los hijos de i ¢ Tamaño de los subárboles de los hijos es a lo más

2n/3

÷ T(n) T(2n/3) + Θ (1) ¢ Por el caso 2 del método maestro ¢ T(n) = O(lgn) ÷ Alternativa ¢ Caracterizar tiempo de ejecución de HEAPIFY sobre un nodo de altura h como: O(h)

O(lgn) ÷   Alternativa ¢   Caracterizar tiempo de ejecución de HEAPIFY sobre un nodo de

Construcción del Heap

10
10

— Uso de heapify para construir el heap

¡ Los elementos A[(floor(n/2) + 1) … n] son hojas del árbol ¡ Orden en que se procesan los nodos garantiza que los subárboles con raíz en los hijos del nodo i son heaps antes de que HEAPIFY se ejecute en dicho nodo

Construcción del Heap

11
11

— Algoritmo BuildHeap

Construcción del Heap 11 —   Algoritmo BuildHeap

Construcción del Heap

12
12
Construcción del Heap 12
Construcción del Heap 12

Análisis BuildHeap

13 13
13
13

— Cada llamada a HEAPIFY ß O(lgn), hay O(n) llamadas

¡ Cuando mucho O(nlgn)

÷ Cota superior pero no justa

¡ Propiedad: En el n-elemento de un HEAP hay a lo más

n / 2 h +

1

nodos de altura h

÷ Tiempo de ejecución de HEAPIFY en nodo altura h à O(h) ÷ Costo de BuildHeap

Análisis BuildHeap 14 14 Del resultado anterior obtenemos el tiempo de ejecución de BuildHeap ⎣
Análisis BuildHeap
14
14
Del resultado anterior obtenemos el tiempo de ejecución de BuildHeap
lg n
lg n
n
h ⎞
O
(
h
)
=
O ⎜ n
*1/ 2
h + 1
h
2
2
h =
0
h
= 0
1
k
Note que
x =
, para | x |
<
1. La derivada de ambos lados,
1 − x
k
=
0
d ⎛
d ⎛
1
1
k
k
− 1
x
⎟ =
⎟ , es igual a
kx
=
.
2
dx
dx
x
(1
1 −
− x
)
k = 0
k = 0
Multiplicando ambos lados de la equivalencia por x obtenemos :
x
k
kx =
.
2
(1
− x
)
h = 0
En nuestro caso k
=
h y x
=
1/2.
h
1/ 2
Entonces
=
=
2,
x
=
1/ 2.
h
2
2
(1
1/ 2)
h
=
0
Entonces el tiempo de ejecución es O(n *1/2 * 2)
=
O(n).

Algoritmo HeapSort

15 15
15
15
Algoritmo HeapSort 15 15

Algoritmo HeapSort

16 16
16
16
Algoritmo HeapSort 16 16
Algoritmo HeapSort 16 16

Análisis de HeapSort

17 17
17
17

— BUILD-HEAP: O(n) — for loop: n-1 veces — Intercambio de elementos: O(1) — MAX-HEAPIFY: O(lgn) — Total time: O(nlgn) — Una implementación buena de QuickSort es mejor que HeapSort

Colas con Prioridades (Priority Queues)

18
18

— Utilizar heaps para implementar colas con prioridades — Priority queue

¡ Estructura de datos para mantener un conjunto S de elementos ¡ Cada elemento tiene un valor asociado llamado à llave ¡ Operaciones

÷ Insert(S,x), inserta x en S, S ß S {x} ÷ Maximum(S), regresa el elemento de S con llave más alta ÷ Extract-Max(S), remueve y regresa el elemento de S con llave más alta

Aplicaciones de Priority Queues

19 19
19
19

— Colas para calendarizar trabajos en una computadora compartida

¡ Mantiene la pista de los trabajos y sus prioridades ¡ Cuando termina un trabajo, inicia el trabajo con más alta prioridad

÷ Extract-Max

¡ Inserta un trabajo en cualquier momento con Insert

Operaciones para Priority Queues

20
20
Operaciones para Priority Queues 20
Operaciones para Priority Queues 20
Operaciones para Priority Queues 20
Operaciones para Priority Queues 20

Tiempo de Ejecuciónpara Priority Queues

21 21
21
21

— Heap-Extract-MAX ß O(lgn) — Heap-Insert ß O(lgn) — Heap-Increase-Key ß O(lgn)

QuickSort

22
22

— Sigue estrategia divide y conquista

¡ Divide

÷ Particiona A[p…r] en 2 subarreglos, A[p…q] y A[q+1…r] ÷ Cada elemento de A[p…q] cada elemento de A[q+1…r] ÷ En esta parte se calcula el índice q

¡ Conquista

÷ A[p…q] y A[q+1…r] son recursivamente ordenados

¡ Combina

÷ No se requiere hacer trabajo en esta parte, A[p…r] queda ordenado

Algoritmo QuickSort

23
23
Algoritmo QuickSort 23

Algoritmo Partition

24 24
24
24

— Existen diferentes algoritmos para particionar

Algoritmo Partition 24 24 —   Existen diferentes algoritmos para particionar

Algoritmo Partition

25 25
25
25
Algoritmo Partition 25 25 —   Gris Claro: partición menor —   Gris Oscuro: partición mayor

— Gris Claro: partición menor — Gris Oscuro: partición mayor — Último elemento: pivote — Blanco: Sin asignar

Performance de QuickSort

26 26
26
26

— Depende de si la partición está o no balanceada

¡ Depende de qué elemento se utilizó para particionar ¡ Partición balanceada

÷ Rápido como MergeSort

¡ Partición no-balanceada

÷ Lento como InsertionSort

Performance de QuickSort

 
 
27 27
27
27

— Peor caso en partición (entrada previamente ordenada)

 

¡ 1 región con n-1 elementos y otra con 1 elemento ¡ Asume que esto sucede en cada paso del algoritmo ¡ Costo de particionar Θ (n), T(1) = Θ (1) ¡ Recurrencia T(n) = T(n-1) + Θ (n)

 
 

n

Serie Aritmética

=

k = 1

Θ ( k )

n

k

=

1

(

n n

+

1)

Θ ⎜

n

k = 1

k

 

2

=

k = 1

2

 

= Θ (

n

)

=

2

Θ ( )

n

 

Performance de QuickSort

28
28

— Mejor Caso en Partición

¡ Regiones de tamaño n/2 ¡ Recurrencia T(n) = 2T(n/2) + Θ (n) ¡ Caso 2, teorema maestro ß T(n) = Θ (nlgn)

Performance de QuickSort

29
29

— Particionamiento balanceado

¡ Caso promedio más cerca del mejor caso que del peor ¡ Suponiendo un split en proporción 9-1ß parece muy desbalanceado ¡ Recurrencia T(n) = T(9n/10) + T(n/10) + n

÷ Vea el árbol de recurrencia en la siguiente lámina

Performance de QuickSort 30 —   Árbol de recurrencia caso de split balanceado
Performance de QuickSort
30
—   Árbol de recurrencia caso de split balanceado

Performance de QuickSort

31
31

— Particionamiento balanceado

¡ Cada nivel tiene costo n ¡ Condición frontera a profundidad log 10 n = Θ (lgn)

÷ Los niveles tienen un costo de cuando mucho n

¡ La recursión termina a profundidad log 10/9 n = Θ (lgn) ¡ Costo total de QuickSort ß = Θ (nlgn)

÷ Para cada split con proporción constante

Performance de QuickSort

32
32

— Intuición para el caso promedio

¡ Partition produce buenos y malos splits

÷ Distribuidos aleatoriamente ÷ Suponga que los buenos y malos alternan (en el árbol) ¢ Bueno à splits del mejor caso ¢ Malo à splits del peor caso ÷ Tiempo de ejecución es todavía Θ (nlgn) ¢ Con una constante más grande escondida por la notación-O

 

Comparación de Algoritmos

 
 
33
33

Algoritmo

Peor

Caso Promedio

Mejor Caso

Comentarios

Caso

InsertionSort

Θ

(n 2 )

Θ

(n 2 )

Θ

(n)

 

MergeSort

Θ (nlgn)

Θ (nlgn)

Θ (nlgn)

Requiere

Memoria

HeapSort

Θ (nlgn)

Θ (nlgn)

Θ (nlgn)

Constantes

Grandes

QuickSort

Θ

(n 2 )

Θ (nlgn)

Θ (nlgn)

Constantes

 

Pequeñas