Ordenamiento - Ciencias Computacionales

Anuncio
Análisis y Diseño de Algoritmos
Ordenamiento – Heapsort y Quicksort
DR. JESÚS A. GONZÁLEZ BERNAL
CIENCIAS COMPUTACIONALES
INAOE
Heaps
2
—  Un Heap es una estructura de datos binaria
¡  Un arreglo que representa un árbol binario completo
Heaps
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
—  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
—  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 subárboles, si no
cumplen con la propiedad del heap
Heapify
7
—  Heap-size[A] à 10
—  A[2], i = 2 no cumple con la propiedad de un heap (MAX-HEAP)
Heapify
8
Heapify
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)
Construcción del Heap
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
—  Algoritmo BuildHeap
Construcción del Heap
12
Análisis BuildHeap
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
h +1
n
/
2
⎡
⎤ nodos de altura h
÷  Tiempo
de ejecución de HEAPIFY en nodo altura h à O(h)
÷  Costo de BuildHeap
Análisis BuildHeap
14
Del resultado anterior obtenemos el tiempo de ejecución de BuildHeap
⎣lg n ⎦
⎣lg n ⎦
⎛
h ⎞
⎡ n ⎤
⎜
⎟
O
(
h
)
=
O
n
*
1
/
2
∑
∑
h ⎟
⎜
⎢⎢ 2 h +1 ⎥⎥
h =0
h = 0 2 ⎠
⎝
∞
Note que ∑ x k =
k =0
1
, para | x | < 1. La derivada de ambos lados,
1− x
∞
d ⎛ ∞ k ⎞ d ⎛ 1 ⎞
1
k −1
,
es
igual
a
kx
=
.
⎜ ∑ x ⎟ = ⎜
⎟
∑
2
dx ⎝ k =0 ⎠ dx ⎝ 1 − x ⎠
(1 − x)
k =0
Multiplicando ambos lados de la equivalencia por x obtenemos :
x
.
2
(1 − x)
h =0
En nuestro caso k = h y x = 1/2.
∞
∑ kx
k
=
h
1/ 2
=
= 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).
∞
Entonces ∑
Algoritmo HeapSort
15
Algoritmo HeapSort
16
Análisis de HeapSort
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
—  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
—  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
Tiempo de Ejecuciónpara Priority Queues
21
—  Heap-Extract-MAX ß O(lgn)
—  Heap-Insert ß O(lgn)
—  Heap-Increase-Key ß O(lgn)
QuickSort
22
—  Sigue estrategia divide y conquista
¡ 
Divide
÷  Particiona
÷  Cada
÷  En
¡ 
elemento de A[p…q] ≤ cada elemento de A[q+1…r]
esta parte se calcula el índice q
Conquista
÷  A[p…q]
¡ 
A[p…r] en 2 subarreglos, A[p…q] y A[q+1…r]
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
Algoritmo Partition
24
—  Existen diferentes algoritmos para particionar
Algoritmo Partition
25
—  Gris Claro: partición menor
—  Gris Oscuro: partición mayor
—  Último elemento: pivote
—  Blanco: Sin asignar
Performance de QuickSort
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
—  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
= ∑ Θ( k )
k =1
⎛ n ⎞
= Θ⎜ ∑ k ⎟
⎝ k =1 ⎠
= Θ( n 2 )
Serie Aritmética
n
∑k =
k =1
1
n(n + 1)
2
= Θ( n 2 )
Performance de QuickSort
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
—  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
31
—  Particionamiento balanceado
¡  Cada nivel tiene costo n
¡  Condición frontera a profundidad log10n = Θ(lgn)
÷  Los
niveles tienen un costo de cuando mucho n
La recursión termina a profundidad log10/9n = Θ(lgn)
¡  Costo total de QuickSort ß = Θ(nlgn)
¡ 
÷  Para
cada split con proporción constante
Performance de QuickSort
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
Algoritmo
Peor
Caso
Caso Promedio
Mejor Caso
Comentarios
InsertionSort
Θ(n2)
Θ(n2)
Θ(n)
MergeSort
Θ(nlgn)
Θ(nlgn)
Θ(nlgn)
Requiere
Memoria
HeapSort
Θ(nlgn)
Θ(nlgn)
Θ(nlgn)
Constantes
Grandes
QuickSort
Θ(n2)
Θ(nlgn)
Θ(nlgn)
Constantes
Pequeñas
Descargar