Heaps
Transcript of Heaps
ARBOLES PARCIALMENTE ORDENADOS
ESTRUCTURAS DE DATOS
www.espol.edu.ec
www.fiec.espol.edu.ec
CONCEPTOS
¨ Arbol Parcialmente Ordenadot Es Binario Completo
e Con propiedad de orden Entre raiz e hijos, la raiz contiene el
mayor(o menor) de todos
e Arbol Binario Completom Todos sus niveles estan completos
s A excepción del ultimo nivel, u Alli las hojas van apareciendo
seguidas de izquierda a derecha
150
125 75
80 30 25 72
15 20 28
UTILIDAD DE UN HEAPE Si el mayor valor esta siempre en la raiz
r El heap presenta un cierto orden
Al remover consecutivamente la raizc Vamos consiguiendo valores ordenados
� El heap se utiliza z Para el ordenamiento de elementos(HeapSort)
e Para implementar colas de prioridad QDesencolarMax, es retirar el valor de la raiz
IMPLEMENTACION
A Un heap no admite “huecos”, e C/nivel se va llenando de izq. A der
e Hay una secuencia
a Podriamos numerar c/nodor En el orden de llenado
150
125 75
80 30 25 72
15 20 28
1
2 3
4 5 6 7
8 9 10
� Si lo vemos asi, dado un índice Podemos conocer los indices de los
hijos y el padre de un nodo
Ejemplo: Del nodo 4, hijos 8 y 9, padre 2
i izq(i) der(i) padre(i)1 2 3 -2 4 5 1
3 6 7 14 8 9 25 10 - 2
6 - - 3
i*2 i*2+1
i/2
CONTANDO DESDE 0L Queremos usar un vector
En c/elemento almacenar la información
m Dirigirnos a hijos y padre calculando el índice respectivo
o Izq(i) = i*2
P Der(i) = i*2+1
P Padre(i) = i/2
P Los vectores en C, empiezan desde 0C Cambia un poquito la reglao Izq(i) = (i+1)*2-1 = i*2+1P Der(i) = (i+1)*2 = i*2+2P Padre(i) = (i+1)/2-1 = (i-1)/2
150
125 75
80 30 25 72
15 20 28
0
1 2
3 4 5 6
7 8 9
150 125 75 80 30 25 72 15 20 280 1 2 3 4 5 6 7 8 9
REGLAS° Vector V de tamaño efectivo n
ñ V[0] es la raizñ Dado un nodo V[i]
] Si 2i+1 < n, V[2i+1] es el hijo izqi Si 2i+2 < n, V[2i+2] es el hijo deri Si i != 0, v[(i-1)/2] es el padre
1 Si es heap
][]2/)1[(:1: ivivnii ≥−<≤∀
DECLARACION: TDA HEAP
Tipo de Datoe Necesitamos un arreglor Llevar el tamaño efectivo Llevar el máximo del arreglo
typedef struct{Generico *Elementos;int nefectivo;int max;Tipo_Orden tipo;
}Heap;
OPERACIONES BASICAS: TDA HEAPC Desencolar y Encolar
o Desencolar: Extraer el elemento mas grande/pequeño del heap(la raiz)a Encolar: Insertar un valor al heap y ubicarlo en la posicion correcta
r HeapSortr Dado un Heap permite generar un arreglo/lista ordenado
m Operaciones Adicionalesi Ajustar
i Reestablece la propiedad de orden de un subheap hacia abajor No a todo el arbol!
o Construir_heap. Dado un arreglo que no representa un heapq Arregla el arreglo y lo convierte en un Heap
MAS OPERACIONES
p int PosIzq(Heap H, int i);
H Retorna el indice del nodo izq de i
e Si no cumple las reglas, retorna -1
int PosDer(Heap H, int i);
H Retorna el índice del nodo der de i
e Si no cumple las reglas, retorna -1
int PosPadre(Heap H, int i);
p Retorna el índice del nodo padre de i
e Si no cumple las reglas, retorna -1
Heap * Heap_Crear(int tmax, TipoOrden t);
r Recibe un heap y lo inicializa para tener un
tamaño maximo tmax y un orden t(ascendente o
descendente)
a bool EstaVacio(Heap P);
e Recibe un Heap y determina si esta Vacio
AJUSTAR
A Recobra la propiedad de orden
e Desde un nodo de índice pos
Dado un índice pos, PosIzq y PosDer
o Se compararan los tres para ver quien tiene el mayor
s Si el mayor lo tiene algun hijo
i Intercambia
A Al hacer esto, el sub-heap afectado puede perder su propiedad de Orden….
l Ajustar el sub-heap afectado
AJUSTAR: EJEMPLO
� Un heap puede perder su p.o.r Por un nodo150
60 75
80 30 25 72
20 70 28
0
1 2
3 4 5 6
7 8 9
150 60 75 80 30 25 72 20 70 280 1 2 3 4 5 6 7 8 9
60
80
Pos
PosMayor
80
60
� Ejemplo:� En el nodo 1 no se cumples Ajustar
s El mayor es el nodo 3o Intercambiaro Ajustar desde nodo
intercambiado(3)
� Ejemplo:� En el nodo 3 no se cumples Ajustar
s El mayor es el nodo 3o Intercambiaro Ajustar Otra Vez
Pos
70PosMayor
70
60
� Ejemplo:� No se puede ajustar un nodo hoja
150 80 75 70 30 25 72 20 60 280 1 2 3 4 5 6 7 8 9
AJUSTAR: IMPLEMENTACIONstatic void Heap_Ajustar(Heap *H, int posnodo, Generico_fnComparar comocomparar){
int pos_mayor, izq, der;pos_mayor = posnodo;izq = IdxIzquierdo(*H, posnodo);der = IdxDerecho(*H, posnodo);if(izq>=0 && Heap_CompararxTipo(H->tipo_orden,H->Elementos[izq],
H->Elementos[posnodo],comocomparar) )pos_mayor = izq;
if(der>=0 && Heap_CompararxTipo(H->tipo_orden,H->Elementos[der], H->Elementos[pos_mayor], comocomparar))
pos_mayor = der;if(pos_mayor != posnodo){
Generico_Intercambiar(&(H->Elementos[pos_mayor]), &(H->Elementos[posnodo]));
Heap_Ajustar(H,pos_mayor,comocomparar);}
}
CONSTRUIR UN HEAP
P La estructura de un heap Puede almacenar un arreglo que no cumpla las propiedades de orden
u Ejemplo: 15 1 28 35 10 5 8 21 50 420 1 2 3 4 5 6 7 8 9
� Hay que arreglar la propiedad de orden
De cada raiz Ajustar c/raiz Desde la ultima a la primera
15
1 28
35 10 5 8
21 50 42
0
1 2
3 4 5 6
7 8 9
CONSTRUIR HEAP: EJEMPLO
� Ajustar el ultimo nodo raiz
o Los nodos raiz comienzan
desde 0 hasta n/2-1
2 Al ajustar cada nodo
n De atrás hacia delante
e Nos aseguramos que los
valores mas altos suban!
15 1 28 35 10 5 8 21 50 420 1 2 3 4 5 6 7 8 9
15
1 28
35 10 5 8
21 50 42
0
1 2
3 4 5 6
7 8 9
42
10
50
35
2850
135
1
50
1542
15
50 42 28 35 15 5 8 21 1 100 1 2 3 4 5 6 7 8 9
CONSTRUIR HEAP: IMPLEMENTACION
void Construir_Heap(Heap *H, Generico_fncomparar comocomparar){
int i;
for(i = H->n/2-1; i >= 0; i--){
Heap_Ajustar(H,i,comocomparar);
}
}
DESENCOLARÈ Que importancia tiene la raiz en el heap?
t Es el mayor/menor elemento del mismo
r Sobre el resto de elementos no estamos seguros
e Pero de la raiz, es la mayor de todos
Desencolar es eliminar la raizi Que valor se ubica en la nueva raiz?
c El ultimo reemplaza al primero
a El tamaño efectivo del heap cambia
v Se ajusta desde la raiz
l El arbol queda bien otra vez
DESENCOLAR: EJEMPLO
P Intercambiar valoreso Raiz con ultimo
o Aminorar tamaño efectivo
e Ajustar arbol
150
125 75
80 30 25 72
15 20 28
0
1 2
3 4 5 6
7 8 9
150 125 75 80 30 25 72 15 20 280 1 2 3 4 5 6 7 8 9
28
28 125 75 80 30 25 72 15 200 1 2 3 4 5 6 7 8
125
28
28
80
125 80 75 28 30 25 72 15 200 1 2 3 4 5 6 7 8
DESENCOLAR: IMPLEMENTACION
Generico Heap_DesEnColar(Heap *H, Generico_fnComparar comocomparar){
Generico gmax;if(!Heap_EstaVacio(*H)){
gmax = H->Elementos[0];Generico_Intercambiar(&(H->Elementos[0]),
&(H->Elementos[H->nefectiva-1]));H->nefectiva --;Heap_Ajustar(H, 0, comocomparar);return gmax;
}return NULL;
}
HEAPSORT° Uno de los usos de los heaps es ordenard Como?
d Extraer el mayor elemento del heap(raiz) Ponerla al final de otro arreglo Repetir los dos ultimos pasos hasta que el Heap quede
Vacio
u El arreglo quedara ordenado
HEAPSORT: EJEMPLO
O Desencolar y ponerlo al
final del nuevo
arreglo/lista
e Repetir hasta que el arbol
quede vacio
150
125 75
80 30 25 72
15 20 28
0
1 2
3 4 5 6
7 8 9
150 125 75 80 30 25 72 15 20 280 1 2 3 4 5 6 7 8 9
28
150
201
252
283
304
725
756
807
1258
1509
125
80
20
28
125 80 75 28 30 25 72 15 200 1 2 3 4 5 6 7 8 9
80
30
15
20
80 30 75 28 20 25 72 150 1 2 3 4 5 6 7 8 9
75
72
15
15
75 30 72 28 20 25 150 1 2 3 4 5 6 7 8 9
72
25
15
15
72 30 25 28 20 150 1 2 3 4 5 6 7 8 9
30
28
20
15
30 28 25 15 200 1 2 3 4 5 6 7 8 9
2815
20
28 20 25 150 1 2 3 4 5 6 7 8 9
2515
15
25 20 150 1 2 3 4 5 6 7 8 9
20
15
20 150 1 2 3 4 5 6 7 8 9
15
150 1 2 3 4 5 6 7 8 90 1 2 3 4 5 6 7 8 9
HEAPSORT: IMPLEMENTACIONLSE *HeapSort(LSE *Desordenada, Generico_fncomparar comocomparar){
Heap H;
LSE_nodo *p;
p = LSE_NodoPrimero(Desordenada); while(!LSE_EstaVacia(Desordenada)) {
Heap_Encolar(&H,LSE_SacarPrimerNodo(Desordenada),comocomparar)
}
while(Heap_EstaVacio(H)){
LSE_InsertarInicio(Desordenada,
Heap_Desencolar(H, comocomparar);
}
return Desordenada;
}
ENCOLAR
U Al añadir un nuevo elemento el Heapv DEBE conservar su propiedad de orden
u Se añade al final del arreglol El elemento empieza a subir a su posición ideal
e Comparando siempre con el padrer Hasta que el valor insertado sea menor que el del
padre
ENCOLAR: EJEMPLO
H Insertar al finall Subir el valor hasta que ya
no sea necesario
150
125 75
80 30 25 72
15 20 28
0
1 2
3 4 5 6
7 8 9
Nuevo valor: 130 150 125 75 80 30 25 72 15 20 280 1 2 3 4 5 6 7 8 9
13010
130
130
30
130
125
ENCOLAR: IMPLEMENTACIONvoid Heap_EnColar(Heap *H, Generico G,
Generico_fnComparar comocomparar){int padre, i;if(H->nefectiva < H->max){
H->Elementos[H->nefectiva] = G;H->nefectiva++;i = H->nefectiva-1;padre = IdxPadre(*H,i);while((i>=0 && padre>=0) &&
Heap_CompararxTipo(H->tipo_orden,H->Elementos[i], H->Elementos[padre], comocomparar)){
Generico_Intercambiar(&(H->Elementos[i]), &(H->Elementos[padre]));
i = padre;padre = IdxPadre(*H,i);
}}
}