eda. tema 8 colas de prioridad: heaps - dsic.upv.esnprieto/clases/eda0203/t8/heaps.pdf ·...

59
EDA. Tema 8 Colas de Prioridad: Heaps Natividad Prieto S ´ aez. DSIC EDA, T-8. Curso 02/03. N.Prieto– p.1/55

Upload: phungduong

Post on 10-Feb-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

EDA. Tema 8Colas de Prioridad: Heaps

Natividad Prieto Saez. DSIC

EDA, T-8. Curso 02/03. N.Prieto– p.1/55

Objetivos

Estudio de las definiciones asociadas a las Colas dePrioridad:

Especificación: operaciones que las caracterizan comoestructuras de datos.Construcción y uso de su interfaz Java:ColaPrioridad.Immplementación usando heaps: claseMonticuloBinario.

Diseño e implementación del método de ordenaciónheapSort

EDA, T-8. Curso 02/03. N.Prieto– p.2/55

Bibliografía

M.A. Weiss. Estructuras de Datos en Java. Ed. AddisonWesley, 2000.Capítulo 6, apartado 8 y capítulo 20,apartados del 1 al 5.

R. Wiener, L.J. Pinson. Fundamental of OOP and DataStructures in Java. Cambridge University Press, 2000.Capítulo 12, apartados 2 y 3.

EDA, T-8. Curso 02/03. N.Prieto– p.3/55

Índice

1. Introducción

Colas de Prioridad

Implementaciones básicas y costes

2. La interfaz ColaPrioridad

3. Los Heaps (Montículos)

4. Implementación de Cola de Prioridad utilizando un Heap

5. El método de ordenación HeapSort

EDA, T-8. Curso 02/03. N.Prieto– p.4/55

Índice

1. Introducción

2. La interfaz ColaPrioridad

3. Los Heaps (Montículos)

4. Implementación de Cola de Prioridad utilizando un Heap

5. El método de ordenación HeapSort

EDA, T-8. Curso 02/03. N.Prieto– p.4/55

Índice

1. Introducción

2. La interfaz ColaPrioridad

3. Los Heaps (Montículos)

Definición y propiedades

Implementación sobre vector

4. Implementación de Cola de Prioridad utilizando un Heap

5. El método de ordenación HeapSort

EDA, T-8. Curso 02/03. N.Prieto– p.4/55

Índice

1. Introducción

2. La interfaz ColaPrioridad

3. Los Heaps (Montículos)

4. Implementación de Cola de Prioridad utilizando un Heap

La operación para insertar

La operación eliminarMin

5. El método de ordenación HeapSort

EDA, T-8. Curso 02/03. N.Prieto– p.4/55

Índice

1. Introducción

2. La interfaz ColaPrioridad

3. Los Heaps (Montículos)

4. Implementación de Cola de Prioridad utilizando un Heap

5. El método de ordenación HeapSort

EDA, T-8. Curso 02/03. N.Prieto– p.4/55

Introducción

Una cola de prioridad es una ED para representarconjuntos con las operaciones:

Acceder al elemento menor de la coleccióny eliminar este elemento

Permiten modelizar:la gestión de un planificador de tareas en un SMU

los trabajos que consumen menos recursos 1o

los trabajos del administrador del sistema 1o

la gestión de los trabajos enviados a impresiónlos trabajos más importantes primerolos trabajos más cortos primero

Para ello, a cada item se le asocia un valor numérico paramedir su prioridad: valores menores implican importanciasmayores

EDA, T-8. Curso 02/03. N.Prieto– p.5/55

Implementación de Colas dePrioridad

¿Qué estructuras de datos podríamos usar paraimplementar una cola de prioridad?

E. Datos buscarMin eliminarMin insertarLista O(N) O(N) O(1)Lista Ord O(1) O(1) O(N)ABB O(log N) O(log N) O(log N)Heaps O(1) O(log N) O(log N)

EDA, T-8. Curso 02/03. N.Prieto– p.6/55

La interfaz ColaPrioridad

import Excepciones.*;

public interface ColaPrioridad {

void insertar (Comparable x);

Comparable buscarMin () throws DesbordamientoInferior;

// devuelve el elemento menor

Comparable eliminarMin () throws DesbordamientoInferior;

// devuelve y elimina el elemento menor

void vaciar ();

boolean esVacia ();

}

EDA, T-8. Curso 02/03. N.Prieto– p.7/55

Heaps

1. Propiedad estructural:

Un Árbol Binario es Completo si tiene todos susniveles completos, a excepción quizás del último, en elcuál todas las hojas están situadas tan a la izquierdacomo sea posible

Propiedades:Su altura es a lo sumo (log N)Admite una representación implícita sobre vector

2. Propiedad de orden:

El valor de cualquier nodo es menor o igual que el desus hijos (Min-Heap)

De manera análoga se define un Max-heap

EDA, T-8. Curso 02/03. N.Prieto– p.8/55

Propiedades

Un heap es un AB completo con la propiedad de ordenenunciada

Propiedades:Todas las ramas del árbol son secuencias ordenadasLa raíz del árbol es el nodo de valor mínimo (o máximoen un Max-Heap)Todo subárbol de un Heap es también un Heap

Cuestiones:¿Cuál es la diferencia entre las propiedades de ordenen los ABB y en los Heaps?¿Puede utilizarse la propiedad de orden en un Heappara listar de forma ordenada las claves del conjunto entiempo lineal?

EDA, T-8. Curso 02/03. N.Prieto– p.9/55

Implementación de Heaps

Representación implícitaVector de objetos, vEntero que representa el tamaño del heap, n

v[1] es la raíz, mínimo en un Min-Heap (o máximo en unMax-Heap)

Dado un nodo v[i],Si 2i ≤ n, v[2i] es el nodo hijo izquierdoSi 2i + 1 ≤ n, v[2i+1] es el nodo hijo derechoSi i 6= 1, v[i/2] es el nodo padre

Propiedad de orden:

∀i : 1 < i ≤ n : v[i/2] ≥ v[i](0)

EDA, T-8. Curso 02/03. N.Prieto– p.10/55

Operaciones básicas

insertar: para añadir un elemento al conjunto. CosteO(log N)

eliminarMin: para devolver y eliminar el elemento menordel conjunto. Coste O(log N)

construirHeap: para convertir un vector en principiodesordenado, en un heap. Coste O(N)

heapSort: para ordenar un vector. Coste O(N log N)

EDA, T-8. Curso 02/03. N.Prieto– p.11/55

Atributos de la claseMonticuloBinario

private Comparable [] vector; // El vector del heapprivate int tamActual; // Numero de elementos del heapprivate static final int CAPACIDAD= 11;

EDA, T-8. Curso 02/03. N.Prieto– p.12/55

La operación constructora

public MonticuloBinario(Comparable infNeg) {

//usa la posicion 0 como centinela vector[0]=-infinito

tamActual=0;

obtenerVector(CAPACIDAD);

vector[0]=infNeg;

}

private void obtenerVector (int nuevoTam) {

// incluye una posici’on extra para el centinela

vector=new Comparable[nuevoTam+1];

}

EDA, T-8. Curso 02/03. N.Prieto– p.13/55

La operación insertar

Añadirlo en la primera posición disponible del vector(tamActual++), para no violar la propiedad estructural delheap

Reflotarlo sobre sus antecesores hasta situarlo en un puntoen el que no se viole la propiedad de orden del heap

Se usará el centinela para evitar tratar como caso especialel del nodo raíz

Antes de insertar se debe comprobar si es necesarioredimensionar el vector

Requiere un coste constante en tiempo medio y logarítmicoen caso peor

EDA, T-8. Curso 02/03. N.Prieto– p.14/55

La operación insertar

public void insertar (Comparable x) {

comprobarTam();

int hueco=++tamActual; //posicion para insercion en vector

while (x.menorQue(vector[hueco/2]) {

vector[hueco]=vector[hueco/2];

hueco=hueco/2;

}

vector[hueco]=x;

}

private void comprobarTam() {

if (tamActual==vector.length-1) {

Comparable [] vectorAnt=vector;

obtenerVector(tamActual*2);

for (int i=0; i<vectorAnt.length; i++)

vector[i]=vectorAnt[i];

}

}

EDA, T-8. Curso 02/03. N.Prieto– p.15/55

Ejemplo de insertar

13

21 16

3124 19

65 26 32

68

EDA, T-8. Curso 02/03. N.Prieto– p.16/55

Ejemplo de insertar

13

21 16

3124 19

65 26 32

68

EDA, T-8. Curso 02/03. N.Prieto– p.17/55

Ejemplo de insertar

13

21 16

24 19

65 26 32

68

31

EDA, T-8. Curso 02/03. N.Prieto– p.18/55

Ejemplo de insertar

13

16

24 19

65 26 32

68

31

21

EDA, T-8. Curso 02/03. N.Prieto– p.19/55

Ejemplo de insertar

13

16

24 19

65 26 32

68

31

21

14

EDA, T-8. Curso 02/03. N.Prieto– p.20/55

Ejercicios

1. Hacer una traza de insertar el valor 3 sobre el heap<0,1,4,8,2,5,6,9,15,7,12,13>

2. Hacer una traza de insertar a partir de un heap vacio lossiguientes valores: 6,4,15,2,10,11,8,1,13,7,9,12,5,3,14

EDA, T-8. Curso 02/03. N.Prieto– p.21/55

Observaciones sobre insertar

El centinela situado en la posición 0 del vector garantiza laterminación del bucle

El coste del método es O(log N) si el elemento añadidofuera el nuevo mínim

En promedio se requieren 2,6 comparaciones para llevar acabo una inserción

EDA, T-8. Curso 02/03. N.Prieto– p.22/55

La operación eliminarMin

El acceso al elemento menor es directo, está en la posición1 del vector

Cuando se elimina este elemento se queda el hueco en laraiz, tamActual disminuye y el último elemento se debe derecolocar para eliminarlo y no violar la propiedad estructuraldel heap

Se debe hundir el hueco en el árbol a través de los hijosmenores hasta que el elemento se pueda colocar sin violarla propiedad de orden del heap

Requiere un coste logarítmico tanto en tiempo medio comoen caso peor

EDA, T-8. Curso 02/03. N.Prieto– p.23/55

Ejemplo de eliminarMin

13

16

19

65 26 32

68

31

21

14

19

EDA, T-8. Curso 02/03. N.Prieto– p.24/55

Ejemplo de eliminarMin

16

19

65 26 32

6821

14

31

19

EDA, T-8. Curso 02/03. N.Prieto– p.25/55

Ejemplo de eliminarMin

16

19

65 26 32

6821

31

14

19

EDA, T-8. Curso 02/03. N.Prieto– p.26/55

Ejemplo de eliminarMin

16

19

65 26 32

6821

31

14

19

EDA, T-8. Curso 02/03. N.Prieto– p.27/55

Ejemplo de eliminarMin

16

19

65 32

6821

31

14

19

26

EDA, T-8. Curso 02/03. N.Prieto– p.28/55

Ejemplo de eliminarMin

16

19

65 32

6821

14

19

26

31

EDA, T-8. Curso 02/03. N.Prieto– p.29/55

La operación eliminarMin

public Comparable eliminarMin () throws DesbordamientoInferior{

if (esVacia()) throws new DesbordamientoInferior("Heap vacio");

Comparable min=vector[1];

vector[1]=vector[tamActual--];

hundir (1);

return min

}

private void hundir (int hueco) {

int hijo; boolean coloca=true;

Comparable tmp=vector[hueco];

while (hueco*2<=tamActual && coloca) {

hijo=hueco*2;

if (hijo!=tamActual && vector[hijo+1].menorQue(vector[hijo]) hijo++;

if (vector[hijo].menorQue(tmp)) {

vector[hueco]=vector[hijo]; hueco=hijo;

} else coloca=false;

}

vector[hueco]=tmp;

}

EDA, T-8. Curso 02/03. N.Prieto– p.30/55

Ejercicios

1. Hacer una traza de eliminarMin sobre el heap<0,1,4,8,2,5,6,9,15,7,12,13>

2. Hacer una traza de hundir(3) sobre el heap<0,1,4,8,2,5,6,9,15,7,12,13>

3. Un Heap Maximal (Max-Heap) soporta las operacionesinsertar y eliminarMax. Implementad esta estructurade datos

EDA, T-8. Curso 02/03. N.Prieto– p.31/55

La operacion arreglarMonticulo

El objetivo es dado un arbol completo restablecer lapropiedad de orden para tener un heap

Coste lineal con el numero de nodos

EDA, T-8. Curso 02/03. N.Prieto– p.32/55

Ejemplo de arreglarMonticulo

20 12 45 63

61 17 55 37 25 64 83 73

47 21

92

EDA, T-8. Curso 02/03. N.Prieto– p.33/55

Ejemplo de arreglarMonticulo

20 12 45 63

61 17 55 37 25 64 83 73

47 21

92

i=7

EDA, T-8. Curso 02/03. N.Prieto– p.34/55

Ejemplo de arreglarMonticulo

20 12 63

61 17 55 37 64 83 73

47 21

92

i=6

45

25

EDA, T-8. Curso 02/03. N.Prieto– p.35/55

Ejemplo de arreglarMonticulo

20 12 63

61 17 55 37 64 83 73

47 21

92

45

25i=5

EDA, T-8. Curso 02/03. N.Prieto– p.36/55

Ejemplo de arreglarMonticulo

12 63

61 55 37 64 83 73

47 21

92

45

25i=4

20

17

EDA, T-8. Curso 02/03. N.Prieto– p.37/55

Ejemplo de arreglarMonticulo

12 63

61 55 37 64 83 73

47 21

92

45

25

20

17

i=3

EDA, T-8. Curso 02/03. N.Prieto– p.38/55

Ejemplo de arreglarMonticulo

63

61 55 64 83 73

21

92

45

25

20

17

i=212

37

47

EDA, T-8. Curso 02/03. N.Prieto– p.39/55

Ejemplo de arreglarMonticulo

63

61 55 64 83 73

21

45

2537

4792

20

17

12i=1

EDA, T-8. Curso 02/03. N.Prieto– p.40/55

La operación arreglarMonticulo

private void arreglarMonticulo () {

for (int i=tamActual/2; i>0; i--)

hundir (i);

}

El coste temporal es lineal con el tamaño del Heap

EDA, T-8. Curso 02/03. N.Prieto– p.41/55

Ordenación rápida: HeapSort

Utilizaremos un Max-Heap (o Heap maximal)

Supondremos que los N elementos a ordenar están en lasposiciones desde 0 hasta N-1

El hijo izquierdo del nodo en posición i está en 2i+1El derecho está en la posición siguienteSi (i!=0) el nodo padre está en (i-1)/2

EDA, T-8. Curso 02/03. N.Prieto– p.42/55

El algoritmo HeapSort

1. Construir un Heap con los elementos del vector

2. Recorremos el vector en sentido descendente, desde elfinal hasta la posición 1. Para cada posición, hacemos:

a) Intercambiamos el valor máximo (v[0]) con el de laposición actual

b) Hundimos el hueco a partir de la posición actualc) Pasamos a analizar la posición anterior

EDA, T-8. Curso 02/03. N.Prieto– p.43/55

El método HeapSort

public static void HeapSort (Comparable v[]) {

for (int i=v.length/2; i>=0; i--)

hundir2(v,i,v.length);

for (int i=v.length; i>0; i--) {

intercambiar(v,0,i);

hundir2(v,0,i);

}

}

EDA, T-8. Curso 02/03. N.Prieto– p.44/55

El método hundir2

private static void hundir2 (Comparable v[], int hueco, int fin) {

int hijo = hueco*2+1 ;

Comparable tmp = v[hueco];

boolean enc = false;

while ( hijo<fin && !enc ) {

if ( hijo!=fin-1 && v[hijo+1].compareTo(v[hijo])>0) hijo++ ;

if ( v[hijo].compareTo(tmp)>0) {

v[hueco] = v[hijo] ;

hueco = hijo;

hijo = hueco *2+1 ;

}

else enc = true;

}

v[hueco] = tmp;

}

EDA, T-8. Curso 02/03. N.Prieto– p.45/55

Ejemplo de heapSort

0 1 2 3 4 5 6 7 8 9

v 8 7 9 3 2 4 1101416

EJEMPLO: ordenacion rapida

14 10

9 3

12 4

8

16

7

EDA, T-8. Curso 02/03. N.Prieto– p.46/55

Ejemplo de heapSort

14 10

9 3

12 4

8

16

7

i=9

10

9 3

2

7

16

14

8

4

1

14 10

9 3

2 4

8 7

1

16

hundir2

EDA, T-8. Curso 02/03. N.Prieto– p.47/55

Ejemplo de heapSort

10

9 3

2

7

16

8

4

1

14

10

9 3

2

7

16

8

4

1

14

3

2

7

16

8

4

14

3

2

7

16

8

4

14

10

9

1

hundir2

10

9 3

2

7

16

14

8

4

1i=8

EDA, T-8. Curso 02/03. N.Prieto– p.48/55

Ejemplo de heapSort

37

16

8

4

14

37

16

8

4

14

9

1

2

10

hundir2

14

i=7

3

2

7

16

8

4

14

3

2

7

16

8

4

14

10

9

1

7

16

8

4

14

7

16

8

4

14

1

10

2

3

9

EDA, T-8. Curso 02/03. N.Prieto– p.49/55

Ejemplo de heapSort

7

16

8

4

14

7

16

8

4

14

1

10

3

2

9

hundir2

i=6

7

16

8

4

14

7

16

8

4

14

1

10

2

3

9

16

4

14 16

4

14

1

10

9

3

8

7

2

EDA, T-8. Curso 02/03. N.Prieto– p.50/55

Ejemplo de heapSort

16

4

14 16

4

14

1

10

9

3

8

7

2

16

4

14 16

4

1410

9

37

2

1

8

hundir2

1614 161410

9

3

2 8

7

4

1

i=5

EDA, T-8. Curso 02/03. N.Prieto– p.51/55

Ejemplo de heapSort

1614 161410

9

3

2 8

7

4

1

1614 161410

9

3

8

4

1

2

7

hundir2

1614 161410

9

3

81 7

2

4

i=4

4

EDA, T-8. Curso 02/03. N.Prieto– p.52/55

Ejemplo de heapSort

1614 161410

9

3

81 7

2

4

1614 161410

9

3

87

2

4

1hundir2

1614 161410

987

2

4

1

3

4

i=3

EDA, T-8. Curso 02/03. N.Prieto– p.53/55

Ejemplo de heapSort

1614 161410

987

2

4

1

3

1614 161410

987

2

4

3

hundir21

1614 161410

9874

31

2

i=2

EDA, T-8. Curso 02/03. N.Prieto– p.54/55

Ejemplo de heapSort

1614 161410

9874

31

2

0 1 2 3 4 5 6 7 8 9

v 2 8 141 3 4 9 107 16

i=1

1614 161410

9874

32

1

EDA, T-8. Curso 02/03. N.Prieto– p.55/55