Tabla de Contenidos
Tabla de Contenidos
Tabla de Contenidos
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
2.2. HEAPSORT 27<br />
Lo primero es notar que i <strong>de</strong>crece, por lo que no po<strong>de</strong>mos hacer inducción en i. Demostraremos<br />
esta propiedad entonces por inducción en la cantidad <strong>de</strong> iteraciones <strong>de</strong>l loop, que llamaremos n.<br />
Note que la relación directa entre n e i es n = N − i.<br />
B.I. Si n = 0 ⇒ i = N, o sea antes <strong>de</strong> empezar el ciclo, sabemos que A cumple la propiedad <strong>de</strong> heap<br />
ya que se ejecutó Build-Heap, luego se cumple (2). Ahora, tanto (1) como (3) se cumplen ya<br />
que los índices quedan fuera <strong>de</strong>l arreglo (no hay nada que <strong>de</strong>mostrar).<br />
H.I. Supongamos que se cumple para n (o equivalentemente para i = N − n), o sea que luego <strong>de</strong>l<br />
paso n–ésimo <strong>de</strong> la iteración las propieda<strong>de</strong>s (1), (2) y (3) son ciertas, es <strong>de</strong>cir:<br />
1. A[N − n..N − 1] está or<strong>de</strong>nado,<br />
2. A[0..N − n − 1] cumple la propiedad <strong>de</strong> heap, y<br />
3. A[0..N − n − 1] ≤ A[N − n..N − 1].<br />
T.I. Analicemos ahora el siguiente paso <strong>de</strong> la iteración, o sea la iteración n+1, lo que querría <strong>de</strong>cir<br />
que i = N −(n+1). Por la H.I. (2) sabemos que A[0] ≥ A[0..N −n−1] ya que A[0..N −n−1]<br />
cumple la propiedad <strong>de</strong> heap, y a<strong>de</strong>más por (3) sabemos que A[0] ≤ A[N − n..N − 1], por lo<br />
que al intercambiar A[0] con A[N − (n + 1)] = A[N − n − 1] se tiene que A[N − n − 1..N − 1]<br />
está or<strong>de</strong>nado y que A[0..N − n − 2] ≤ A[N − n − 1..N − 1]. Ahora el cambio pudo haber<br />
hecho que A[0..N − n − 2] <strong>de</strong>jara <strong>de</strong> cumplir la propiedad <strong>de</strong> heap. Hay que notar que justo<br />
antes <strong>de</strong> la llamada a Heapify el valor <strong>de</strong> π cumple con π = i = N −n−2, por lo que luego <strong>de</strong><br />
la llamada a Heapify, estaremos seguros que A[0..N − n − 2] cumple la propiedad <strong>de</strong> heap.<br />
Finalmente hemos <strong>de</strong>mostrado que:<br />
- A[N − (n + 1)..N − 1] está or<strong>de</strong>nado,<br />
- A[0..N − (n + 1) − 1] cumple la propiedad <strong>de</strong> heap, y<br />
- A[0..N − (n + 1) − 1] ≤ A[N − (n + 1)..N − 1].<br />
Por inducción se sigue que la propiedad se cumple para toda iteración <strong>de</strong>l loop principal.<br />
Finalmente cuando el loop termina, tenemos que i = 1, o sea que n = N − 1, <strong>de</strong> don<strong>de</strong> se concluye<br />
(reemplazando n = N −1 en (1) y (3)) que <strong>de</strong>spués <strong>de</strong> la última iteración A[0..N −1] está or<strong>de</strong>nado.<br />
Complejidad <strong>de</strong> Heapsort<br />
Para analizar la complejidad <strong>de</strong> Heap-Sort lo primero que notamos es que se ejecuta una vez<br />
el procedimiento Build-Heap y que el procedimiento Heapify se ejecuta Θ(N) veces. Dado que<br />
Build-Heap toma tiempo Θ(N) y que Heapify toma tiempo Θ(log N) cuando se ejecuta <strong>de</strong>s<strong>de</strong> la<br />
raíz <strong>de</strong> un heap con N elementos, po<strong>de</strong>mos asegurar que Heap-Sort toma tiempo O(N+N log N) =<br />
O(N log N) en el peor caso. ¿Po<strong>de</strong>mos dar una cota más ajustada como lo hicimos en el caso <strong>de</strong><br />
Build-Heap? La respuesta esta vez es no. Un argumento a favor para intentar encontrar una cota<br />
más ajustada es el hecho <strong>de</strong> que Heapify no se ejecuta siempre sobre un heap <strong>de</strong> N elementos, <strong>de</strong><br />
hecho, en cada iteración se disminuye el valor <strong>de</strong> π lo que nos dice que en cada iteración Heapify<br />
se ejecuta sobre un heap cada vez más pequeño. Un argumento muy fuerte en contra <strong>de</strong> intentar<br />
✷