Download Cap. 21. Colas de prioridad. Pairing heaps.

Document related concepts

Heap Binomial wikipedia , lookup

Montículo de Fibonacci wikipedia , lookup

Árbol binario wikipedia , lookup

Montículo (informática) wikipedia , lookup

Treap wikipedia , lookup

Transcript
1
Capítulo 21
Heaps Binomiales. Seleccionar.
Una cola de prioridad binomial considera los datos almacenados en una foresta; ésta puede ser
definida como una colección de subárboles, en la que cada subárbol es un árbol binomial; y tal
que cada uno de ellos cumple la propiedad de que los hijos tienen claves o prioridades mayores
o iguales a las del padre. Esta estructura favorece la operación de mezclar dos colas de
prioridad, para formar una nueva.
21.1. Árbol binomial.
Un árbol binomial B p 1 , de orden p+1, es un multiárbol formado por la unión de dos árboles
0 . B0 está formado por un elemento. Entendemos por unión el
que la raíz de uno de los árboles binomiales B p es el hijo más izquierdista de la raíz del otro
binomiales de orden p, para p
árbol binomial B p , según se muestra en la Figura 21.1.
B0
Bp+1
Bp
Bp
Figura 21.1. Definición inductiva de árbol binomial.
La Figura 21.2, muestra algunos ejemplos de árboles binomiales.
B0
B1
B2
B3
Figura 21.2. Ejemplos de árboles binomiales.
Puede demostrarse por inducción que un árbol binomial B p tiene 2 p nodos; que la raíz tiene p
hijos; y que la máxima profundidad del árbol es p.
Profesor Leopoldo Silva Bijit
20-01-2010
2
Estructuras de Datos y Algoritmos
Es importante destacar que si n 2 p , entonces: p log 2 (n) . Las principales operaciones sobre
esta estructura dependen del número de hijos de la raíz.
Si se enumeran los nodos, empleando el sistema binario, en preorden (izquierdo-derecho-raíz),
partiendo del nodo con mayor profundidad, se obtiene la Figura 21.3, para el caso de B3 .
111
011
001
010
101
110
100
000
Figura 21.3. Numeración binaria en preorden de B3.
Se tienen
p
k
nodos con profundidad k en B p . Debido al coeficiente binomial, que figura en la
relación anterior, se da el nombre de binomiales a estos árboles.
Para la raíz y el nodo más profundo de B p , se tienen:
Los p hijos de la raíz de B p , se obtienen de:
p
1
p
p
p
0
p!
1!( p 1)!
1.
p.
Los valores de los coeficientes binomiales corresponden al número de secuencias binarias de p
bits, con exactamente k ceros. También puede comprobarse que las hojas tienen números pares;
y que el número de hijos de un nodo es el número de unos que siguen al último cero de su
numeración binaria.
Como Bp está formado por la unión de dos árboles Bp-1, un nodo a profundidad k en Bp-1 aparece
en Bp una vez a profundidad k y una vez a profundidad k + 1. Entonces para obtener los nodos a
profundidad k en Bp debemos sumar los nodos a profundidad k en Bp-1, más los nodos a
profundidad k-1 en Bp-1.
k-1
k
Figura 21.4. Nodo con profundidad k en Bp.
Considerando verdadera la proposición inductiva, debería cumplirse:
Profesor Leopoldo Silva Bijit
20-01-2010
Colas de prioridad. Heaps Binomiales.
3
p
p 1
p 1
k
k
k 1
Desarrollando el lado derecho, y aplicando la definición de coeficiente binomial, se obtiene:
( p 1)!
( p 1)!
k !( p 1 k )! (k 1)!( p 1 (k 1))!
Sacando factores comunes, y multiplicando y dividiendo el segundo término por k, se tiene:
( p 1)!
1
k
(
)
k!
( p 1 k )! ( p k )!
Multiplicando y dividiendo el primer término por p-k, factorizando y aplicando la definición de
coeficiente binomial, se tiene:
( p 1)!
(( p k ) k )
k !( p k )!
p!
k !( p k )!
p
k
Lo que demuestra la propiedad.
Una forma alternativa de definir B p 1 , es agregar como hijos de la raíz a los (p+1) árboles
binomiales: B p , B p 1 , B p 2 ,..., B2 , B1 , B0 . La Figura 21.5, muestra la generación de B3 .
B3
B2
B1
B0
Figura 21.5. Subárboles de B3.
21.2. Cola de prioridad binomial.
Si se desea representar conjuntos de n elementos, tal que n no sea una potencia de dos, puede
considerarse la representación de n en el sistema binario, mediante la secuencia de (p+1) cifras
binarias, con el equivalente decimal:
i p
bi 2i
n
i 0
Profesor Leopoldo Silva Bijit
20-01-2010
4
Estructuras de Datos y Algoritmos
Donde bi es uno de los dígitos binarios {0, 1}. Se define la foresta binomial Fn de orden n,
como una colección finita de árboles binomiales Bi , uno por cada cifra bi diferente de cero en la
representación binaria de n.
Por ejemplo para n=13, se tiene: F13
B3 , B2 , B0 ya que 1310
11012
Entonces una cola de prioridad de n elementos puede ser representada por una foresta Fn , donde
cada uno de los árboles binomiales que la forman, cumplen la propiedad de que los hijos tienen
prioridades mayores que la de su padre.
Observando la Figura 21.5, una cola de prioridad con n elementos también puede representarse
con la raíz como el nodo con prioridad mínima unido a una foresta Fn-1.
21.3. Análisis de la operación unión.
Dadas dos forestas: Fn y Fm la unión estará formada por (n+m) elementos en una foresta Fn m .
Es notable que la operación mezcla pueda realizarse en forma similar a una suma binaria. El
siguiente ejemplo describe el algoritmo:
Se desea obtener la mezcla de F13
B3 , B2 , B0 con F5
B2 , B0 . La suma binaria de 13 y
5, se realiza según:
1 1 0 1
+ 0 1 0 1
1 0 0 1 0
Al sumar (unir, mezclar o fundir) dos árboles binomiales Bi se produce reserva, ésta es un árbol
binomial Bi 1 .
+
B4
B3 B2
B2
Entonces, para el ejemplo, resulta: F18
B0
B0
B1
B4 , B1 .
Observando la Figura 21.2, puede notarse que la unión de dos árboles binomiales puede
realizarse en tiempo constante, basta escribir una referencia para el árbol descendiente. En el
peor caso un heap con n elementos está formado por log(n) árboles binomiales, entonces
obtener uno, mediante mezclas, demanda un costo O(log(n)).
La inserción puede realizarse como la mezcla de un árbol binomial con un elemento con la
estructura ya existente. También su costo es O(log(n)).
Profesor Leopoldo Silva Bijit
20-01-2010
Colas de prioridad. Heaps Binomiales.
5
La extracción del mínimo requiere buscar la raíz menor de los árboles binomiales que forman la
foresta, esto tiene un costo O(log(n)), ya que ese es el número de heaps que forman la cola de
prioridad. Observando la Figura 21.5, la remoción de la raíz de uno de los árboles binomiales
genera una nueva foresta, la cual debe unirse al resto de los árboles binomiales, lo cual se
realiza también en O(log(n-1)), dando para la operación completa un costo O(log(n)).
21.4. Estructura de datos.
La Figura 21.6, muestra las prioridades almacenadas en los multiárboles binomiales: B3 , B2, B1 ,
B0.
1
1
2
2
1
1
3
4
2
5
3
6
7
4
8
Figura 21.6. Multiárboles binomiales: B3 , B2, B1 , B0.
21.4.1. Nodo binario.
Inicialmente se considera un nodo binario, que minimiza el tamaño de memoria ocupada por el
nodo.
La Figura 21.7, muestra una posible estructura que emplea los punteros derechos para
referenciar el hijo más derechista del nodo, y los punteros izquierdos para enlazar los hermanos
hacia la izquierda. Las listas de hermanos son circulares: Si no hay hermanos de un nodo, el
puntero izquierdo apunta al mismo nodo; el último nodo de la lista de hermanos apunta al
hermano más derechista. Las hojas tienen punteros derechos, o hacia abajo, nulos.
Se han ilustrado árboles binomiales, donde la raíz tiene lista izquierda vacía, sin embargo puede
acordarse unir los árboles binomiales de la foresta en la lista circular de la raíz.
Profesor Leopoldo Silva Bijit
20-01-2010
6
Estructuras de Datos y Algoritmos
1
1
1
2
2
1
3
2
5
3
4
6
7
4
8
Figura 21.7. Representación mediante listas.
Por ejemplo si a B1 en la Figura 21.7, se agrega un nodo con prioridad 3, el árbol binomial B0,
que lo representa, se coloca en la lista izquierda de la raíz, esto se muestra en la Figura 21.8.
Debe notarse que la operación es sencilla si el número de elementos en la foresta es par; ya que
esto implica agregar el árbol binomial B0, formado por un elemento.
3
1
2
Figura 21.8. Foresta con 3 elementos.
Si en B2 en la Figura 21.7, se agregan nodos con prioridades 5 y 6, debe formarse el árbol
binomial B1 , el cual se coloca en la lista izquierda de la raíz, formando una foresta de 6
elementos, esto se muestra en la Figura 21.9, a la izquierda. Nótese que después de agregado el
5, debe procederse a formar, mediante la unión o suma un árbol binomial B1, formado por los
elementos 5 y 6.
A la derecha de la Figura 21.8, se muestra un foresta con 7 elementos, donde se ha enlazado B0,
formado por el nodo con valor 7, con B1 y B2. Esta inserción también es sencilla.
Profesor Leopoldo Silva Bijit
20-01-2010
Colas de prioridad. Heaps Binomiales.
5
2
6
7
1
5
3
6
7
1
2
3
4
4
Figura 21.9. Foresta con 6 y 7 elementos.
La inserción del elemento con valor 8, en el heap a la derecha de la Figura 21.9, debería formar
el árbol binomial B3, que se muestra a la derecha de la Figura 21.7. Esto se logra con la unión de
dos árboles B1, para formar un árbol B2; y luego la suma de dos árboles B2, para formar un árbol
B3.
+
B3
B2 B1 B0
B0
Figura 21.10. Generación de B3 mediante mezclas.
21.4.2. Nodo binario aumentado con información del grado.
Si se almacena el número de elementos en la foresta, su representación binaria indica los árboles
binomiales que la forman. Si al inicio, antes de insertar, el número de elementos es impar, esto
indica que está presente B0; y si es par, indica que la foresta no contiene a B0. La división
sucesiva de este número por dos va indicando, en la cifra binaria menos significativa, si están
presentes en la cola de prioridad los árboles binomiales B1, B2, y así sucesivamente. Sin
embargo, con esta estructura, la operación para extraer el mínimo es compleja de codificar.
Si se almacena el grado del árbol binomial en el nodo, puede representarse la foresta como una
lista enlazada de las raíces de los árboles binomiales ordenadas por grado, ya que esto facilita la
operación unión de dos árboles binomiales de igual grado. Sin embargo el descarte del mínimo
requiere recorrer la lista completa, pero el largo de ésta está acotada; el largo, en el peor caso, es
el logaritmo del número de nodos almacenados en la cola de prioridad. Para representar los
multiárboles se emplea la organización hijo más izquierdista-hermano derecho.
La Figura 21.11, muestra los multiárboles binomiales B2 y B3 de la Figura 21.6, empleando el
enlace izquierdo del nodo binario para apuntar al hijo más izquierdista, y el enlace derecho para
apuntar al hermano derecho; en cada nodo se almacena la prioridad y el grado del árbol
binomial asociado al nodo. Nótese que dentro del árbol binomial, las listas de hermanos están
ordenadas en forma descendente según el grado, esto facilita la operación unión de dos árboles
binomiales de igual grado, basta escribir dos punteros e incrementar el grado de la nueva raíz.
Esto se ilustra a la derecha de la Figura 21.11, destacando los dos árboles que se unen.
Profesor Leopoldo Silva Bijit
20-01-2010
8
Estructuras de Datos y Algoritmos
1
3
3
1
5
2
1
2
3
1
7
1
2
0
6
0
2
0
4
0
8
0
4
0
Figura 21.11. Representación hijo izquierdo-hermano derecho de B2 y B3.
La Figura 21.12, muestra una cola de prioridad con 13 nodos, mediante el enlace de tres árboles
binomiales: B0, B2 y B3. El enlace derecho de las raíces de los árboles binomiales se emplea
para formar una lista ordenada en forma descendente por grado; debe notarse que no quedan
ordenados por prioridad. El ejemplo muestra que el nodo con prioridad mínima puede estar en
cualquier posición de la lista; en la Figura 21.12, se ilustra al final de ésta.
9
0
1
3
10
2
11
1
12
0
3
1
5
2
7
1
14
0
6
0
2
0
4
0
8
0
Figura 21.12. Foresta con 13 nodos. Lista de raíces.
Ordenando de este modo la lista, se facilita la operación de unir (o sumar) dos forestas. Equivale
a realizar las sumas binarias desde los dígitos menos significativos.
21.4.3. Nodo binario con punteros al padre.
Si se desea disponer de operaciones de búsqueda o de decrementar la prioridad de un nodo, para
que estas operaciones resulten eficientes, debe agregarse un puntero al padre.
21.5. Análisis de la inserción.
Si la foresta no contiene un árbol binomial B0, la inserción coloca el nuevo nodo al comienzo de
la lista de raíces. Si está presente B0, se une a éste el nodo que se desea insertar, formando un
árbol binomial B1; y debe seguirse efectuado uniones si pueden formarse árboles binomiales de
mayores grados, esto se realiza recorriendo la lista de raíces.
Profesor Leopoldo Silva Bijit
20-01-2010
Colas de prioridad. Heaps Binomiales.
9
Si antes de la inserción, la foresta no puede tener dos árboles binomiales de igual grado,
entonces la lista debe recorrerse mientras el grado de la última unión sea igual al grado del
siguiente árbol binomial de la lista.
21.6. Análisis de la extracción del mínimo.
Se recorre la lista hasta encontrar el mínimo, y se liga la lista con el siguiente. Los hijos del
nodo mínimo forman otra lista de árboles binomiales; sin embargo, debido a la construcción,
está ordenada por grados en forma descendente. Entonces se debe reversar la lista de hijos del
nodo mínimo, dejándola ordenada en forma ascendente por grado.
Luego se procede a mezclar las dos listas ordenadas por grados, dejando adyacentes a los nodos
que tengan grados iguales. Luego debe procederse a unir los árboles de igual grado, y si es
posible, formar árboles de mayores grados; esta operación debe recorrer la lista completa.
21.7. Tipos de datos.
Se considera un nodo binario más la información del grado. De ser necesario puede emplearse
un puntero al padre.
typedef struct bintree
{ //struct bintree * padre;
struct bintree * hijo;
struct bintree * hermano;
int prioridad;
int grado;
} nodo, *pnodo;
//puntero al hijo más izquierdista.
//apunta al hermano derecho
typedef pnodo queue;
21.8. Creación de nodo.
pnodo getnodo(int prioridad)
{ pnodo p=NULL;
if ( (p= (pnodo) malloc(sizeof(nodo))) ==NULL)
{ printf("Error: Memoria. \n"); exit(1);}
else
{ p->prioridad=prioridad; p->grado=0;
//p->padre=NULL;
p->hijo=NULL; p->hermano=NULL;
}
return(p);
}
21.9. Inicio de cola.
void initqueue( queue *q )
Profesor Leopoldo Silva Bijit
20-01-2010
10
Estructuras de Datos y Algoritmos
/* inicia una variable de tipo cola de prioridad */
{
*q = NULL;
} /* initqueue */
21.10. Test de cola vacía.
int emptyqueue( queue q )
/* Retorna 1 si la cola está vacía */
{
return (q == NULL);
} /* emptyqueue */
21.11. Unión de dos árboles binomiales de igual grado.
Enlaza árbol de grado (k-1) con raíz mayorp, con árbol de grado (k-1) con raíz menorp, por
nodo con menor prioridad. Ver Figura 1.
Donde menorp es el padre de mayorp, y además es la raíz de un nuevo árbol de grado k. Se
coloca como comentario, la mantención de punteros al padre.
void BinomialLink(pnodo mayorp, pnodo menorp)
{ //mayorp->padre=menorp;
mayorp->hermano=menorp->hijo;
menorp->hijo= mayorp;
menorp->grado++;
}
menorp
1
3
mayorp
3
1
5
2
7
1
6
0
2
0
4
0
8
0
Figura 21.13. Enlace de dos árboles de grado 2.
21.12. Mezcla dos listas ordenadas por campo grado.
pnodo BinomialHeapMerge(pnodo H1, pnodo H2)
{ pnodo H=NULL, t;
if (H1==NULL ) return H2; else if (H2==NULL) return H1;
Profesor Leopoldo Silva Bijit
20-01-2010
Colas de prioridad. Heaps Binomiales.
11
else
{ if (H1->grado < H2->grado) {H=H1; H1=H1->hermano;} //Inicio lista
else {H=H2; H2=H2->hermano;}
t=H;
while(H1!=NULL && H2!=NULL) //se pasan en orden ascendente
{ if (H1->grado < H2->grado){t->hermano=H1; H1=H1->hermano;}
else {t->hermano=H2; H2=H2->hermano;}
t=t->hermano;
}
if (H1!=NULL ) t->hermano=H1; //copia el resto de la lista que no se agotó
else t->hermano=H2;
return(H);
}
}
Puede compactarse la codificación de la función si se emplea un nodo de encabezado, de este
modo la inicialización de la mezcla se realiza dentro del lazo while.
pnodo BinomialHeapMerge(pnodo H1, pnodo H2)
{ nodo h;
pnodo t=&h;
while (H1!=NULL && H2!=NULL)
{ if (H1->grado < H2->grado){t->hermano=H1; H1=H1->hermano;}
else {t->hermano=H2; H2=H2->hermano;}
t=t->hermano;
}
if (H1==NULL ) t->hermano=H2;
else if (H2==NULL ) t->hermano=H1; else t->hermano=NULL;
return ((&h)->hermano);
//retorna puntero a la mezcla.
}
21.13. Mezcla dos colas binomiales.
Es la operación fundamental de la estructura. Su costo depende del largo de la lista de árboles
binomiales.
Si dos árboles adyacentes son de grados diferentes, debe seguir revisando la lista. También debe
seguir revisando sin efectuar enlaces, si se encuentran tres árboles binomiales de igual grado; si
esto ocurre, avanza una posición, dejando uno de los árboles y mezclando los dos siguientes.
Este caso equivale a la suma de dos dígitos binarios con reserva.
La función emplea tres punteros para el análisis de los casos: un puntero al nodo previo, otro al
actual, y otro al siguiente. Al inicio el puntero previo apunta a nulo.
Debido a que los operadores lógicos operan con cortocircuitos, la realización de la segunda
parte de un or, sólo se efectúa si el primer operando es falso; ya que si el primero es verdadero
la condición será verdadera no importando el valor lógico de la segunda. Entonces, la detección
de tres adyacentes iguales puede codificarse, como el segundo término del or, según:
Profesor Leopoldo Silva Bijit
20-01-2010
12
Estructuras de Datos y Algoritmos
(x->grado != nextx->grado ||
( (nextx->hermano!= NULL) && (nextx->hermano->grado == x->grado)) )
La formulación de la segunda parte del or, se plantea mediante un and lógico para asegurar la
existencia del tercer nodo; ya que si no existe el tercer nodo, preguntar por su grado produce un
error en ejecución.
El caso 1, se produce cuando los nodos raíces tienen grados diferentes, y se activa con la
primera parte del or. El caso 2, se presenta cuando existe suma de árboles binomiales de igual
grado con reserva.
Cuando debe efectuarse el enlace binomial de dos árboles de igual grado, se tienen dos casos
que se disciernen según la prioridad de los nodos raíces. Son los casos 3 y 4. Se emplea el
puntero previo para enlazar las listas.
pnodo BinomialHeapUnion(pnodo H1, pnodo H2)
{ pnodo H=NULL, prevx, nextx, x;
H = BinomialHeapMerge(H1, H2);
if (H ==NULL) return H;
prevx = NULL;
x = H;
nextx = x->hermano;
while (nextx != NULL)
{ //Si grado de x y siguiente son diferentes o tres de grados iguales
if (x->grado != nextx->grado ||
((nextx->hermano!= NULL) && (nextx->hermano->grado == x->grado)) )
{ prevx = x;
// Casos 1 y 2. Avanza sin enlazar árboles.
x = nextx;
}
//Entra al else: Si grados de x y siguiente son iguales
//y no hay tres nodos de iguales grados adyacentes.
else if (x->prioridad <= nextx->prioridad ) // Caso 3
{ x->hermano = nextx->hermano;
//Liga lista y deja
BinomialLink(nextx, x);
//x como raíz
}
else
{if (prevx == NULL) H = nextx; // Caso 4
else prevx->hermano= nextx;
//Liga lista y deja a
BinomialLink(x, nextx);
//nextx en la raíz
x = nextx;
//actualiza el nodo denominado actual
}
nextx = x->hermano; //avanza al siguiente
}
return H;
}
Profesor Leopoldo Silva Bijit
20-01-2010
Colas de prioridad. Heaps Binomiales.
13
21.14. Insertar.
Se pasa la cola de prioridad con una referencia a ésta.
Encola nodo n en cola referenciada por q, empleando la operación de unión.
void enqueue( pnodo n, queue *q )
{ pnodo p=*q;
*q= BinomialHeapUnion(p, n);
} /* enqueue */
Una pequeña refinación de la operación, se logra aislando dos situaciones triviales. La primera
es que la cola esté vacía; la otra es que el número de nodos en la foresta sea par, en este caso no
hay al principio de la lista un árbol binomial de un nodo, o de grado cero, y basta insertar al
inicio. Puede especializarse aún más la operación, ya que en este caso no pueden presentarse
tres árboles de igual grado, y tampoco es preciso recorrer toda la lista.
void enqueue( pnodo n, queue *q )
{ pnodo p=*q;
if (p==NULL) *q=n;
else if (p->grado!=0) {n->hermano=*q; *q=n;}
else
*q= BinomialHeapUnion(p, n);
} /* enqueue */
21.15. Descartar.
La operación desencolar retorna el nodo con valor mínimo de prioridad, y deja una foresta
disminuida en un elemento.
Para esto, luego de extraer de la lista el árbol binomial cuya raíz es el nodo con prioridad
mínima, deja ligada la lista con los árboles binomiales siguientes al que contiene el mínimo.
Posteriormente reversa el orden de la lista de hijos del mínimo, dejándola ordenada ascendente.
Finalmente realiza la suma de las dos forestas.
pnodo dequeue( queue *q )
{ pnodo p=*q, min, ListaHijosMinimo;
if (p==NULL) return NULL;
min=ExtraeMinimo(q);
//Se enlaza lista sin el árbol cuya raíz es el mínimo
//reversar lista descendente (ordenada por grado) de hijos del mínimo, apuntada por x.
ListaHijosMinimo=ReversarLista(min->hijo);
//Queda lista ordenada ascendente por grado, apuntada por x.
//Se mezcla lista de árboles sin el mínimo, con la lista de hijos del mínimo
*q=BinomialHeapUnion(*q, ListaHijosMinimo);
return (min);
} /* dequeue */
Profesor Leopoldo Silva Bijit
20-01-2010
14
Estructuras de Datos y Algoritmos
21.16. Extracción del mínimo.
Se emplean variables locales que apuntan al nodo actual de la lista p, y al nodo mínimo min.
Además para facilitar el ligado de la lista se emplean punteros al padre de p (pp) y al padre de
min (pm). Se enlaza lista sin el árbol cuya raíz es el mínimo
pnodo ExtraeMinimo(queue *q)
{ pnodo p=*q, min, pm, pp;
//pp padre de p (hermano izquierdo de p). pm padre del minimo.
pp=NULL; //al inicio p no tiene padre
//min apunta al mínimo. Al inicio apunta al primer nodo de la lista.
min=p; pm=pp;
pp=p; p=p->hermano; //Avanza al siguiente de la lista
while (p!=NULL)
{ if (min->prioridad > p->prioridad) { min=p; pm=pp;}
pp=p; p=p->hermano;
}
if (pm==NULL) *q=min->hermano; //cambia la raíz. Si el mínimo era el primero.
else pm->hermano=min->hermano; //liga resto de la lista
return (min);
}
El código puede simplificarse usando un nodo de encabezado, lo que permite tratar al primer
nodo dentro del lazo while. Se coloca el máximo valor de prioridad en el nodo centinela, de
acuerdo al tipo del campo prioridad; estos valores se encuentran en <limits.h>.
pnodo ExtraeMinimo(queue *q)
{ nodo n ={NULL, NULL, INT_MAX, 0};
//centinela con la prioridad mayor posible
pnodo p=*q, min=&n, pm, pp=NULL;
while (p!=NULL)
{ if (min->prioridad > p->prioridad) { min=p; pm=pp;}
pp=p; p=p->hermano;
}
if (pm==NULL) *q=min->hermano; //cambia la raíz
else pm->hermano=min->hermano; //liga resto de la lista
return(min);
}
21.17. Reversar Lista.
Reversar lista descendente, ordenada por grado, de hijos del mínimo, apuntada por x, dejándola
ordenada en forma ascendente. La operación contempla el caso en que la estructura emplee
punteros al padre, dejando como comentarios las mantenciones de esos punteros.
Se emplean los punteros y y t, para recorrer la lista. Donde y es el siguiente de x, y t el siguiente
de y.
Profesor Leopoldo Silva Bijit
20-01-2010
Colas de prioridad. Heaps Binomiales.
pnodo ReversarLista(pnodo x)
{ pnodo y, t;
if (x!=NULL)
{ //x->padre=NULL;
y=x->hermano;
x->hermano=NULL;
while(y!=NULL)
{ //y->padre=NULL;
t=y->hermano;
y->hermano=x;
x=y; y=t;
}
}
return(x);
}
15
//Inicia siguiente del primero de la lista.
//Inicia el primer nodo como el último o fin de lista
//salva dirección del siguiente
//apunta hacia atrás
//recorre la lista
21.18. Busca mínimo.
La siguiente función retorna un puntero al nodo con valor de prioridad mínima, pero no lo
extrae de la foresta.
/*retorna puntero al nodo con prioridad mínima en un heap binomial con n elementos*/
pnodo BinomialHeapMinumun(queue *q)
{
pnodo pmin =NULL; //puntero al mínimo, aún no se conoce
pnodo p =*q;
int min =INT_MAX;
while (p!=NULL)
{ if (p->prioridad < min) { min = p->prioridad; pmin = p;}
p =p->hermano;
}
return pmin;
}
21.19. Lista de raíces de árboles binomiales.
Para ayudar a la depuración de la funciones es conveniente disponer de un listador simple de la
estructura.
//lista raíz-grado
int prtbinomial(queue *q)
{
pnodo p=*q, t;
if (p!=NULL) printf("%d-%d ", p->prioridad, p->grado);
else {printf("Binomial nulo\n"); return(0);}
Profesor Leopoldo Silva Bijit
20-01-2010
16
Estructuras de Datos y Algoritmos
for(t=p->hermano; t!=NULL ; t=t->hermano)
printf("%d-%d ", t->prioridad, t->grado);
putchar('\n');
return(1);
}
21.20. Test de las funciones.
queue binomial=NULL;
#define N 30
int main (void)
{ pnodo t;
int i;
initqueue( &binomial);
srand(1);
for(i=1;i<=N;i++)
{ enqueue2(getnodo(rand()%100), &binomial);
//prtbinomial(&binomial);
}
putchar('\n');
for(i=1;i<=N;i++)
{ t= dequeue(&binomial);
//prtbinomial(&binomial);
printf(" %d ", t->prioridad);
free(t);
}
putchar('\n');
return(0);
}
Referencias.
J. Vuillemin, “A Data Structure for Manipulating Priority Queues”, CACM Vol. 21, No. 4,
April 1978, 309-315.
M. R. Brown. PhD thesis, “The Analysis of a Practical and Nearly Optimal Priority Queue”,
Stanford University, March 1977.
Douglas W. Jones, “An Empirical Comparison of Priority-Queue and Event-Set
Implementations”, Communications of the ACM, April 1986, Volume 29, Number 4.
Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. “Introduction
to Algorithms”, Second Edition. MIT Press and McGraw-Hill, 2001.
Profesor Leopoldo Silva Bijit
20-01-2010
Colas de prioridad. Heaps Binomiales.
17
Índice general.
CAPÍTULO 21 ........................................................................................................................................... 1
HEAPS BINOMIALES. SELECCIONAR. ............................................................................................. 1
21.1. ÁRBOL BINOMIAL. ........................................................................................................................... 1
21.2. COLA DE PRIORIDAD BINOMIAL. ...................................................................................................... 3
21.3. ANÁLISIS DE LA OPERACIÓN UNIÓN. ................................................................................................ 4
21.4. ESTRUCTURA DE DATOS................................................................................................................... 5
21.4.1. Nodo binario. .......................................................................................................................... 5
21.4.2. Nodo binario aumentado con información del grado. ............................................................ 7
21.4.3. Nodo binario con punteros al padre........................................................................................ 8
21.5. ANÁLISIS DE LA INSERCIÓN. ............................................................................................................ 8
21.6. ANÁLISIS DE LA EXTRACCIÓN DEL MÍNIMO. ..................................................................................... 9
21.7. TIPOS DE DATOS............................................................................................................................... 9
21.8. CREACIÓN DE NODO......................................................................................................................... 9
21.9. INICIO DE COLA................................................................................................................................ 9
21.10. TEST DE COLA VACÍA. .................................................................................................................. 10
21.11. UNIÓN DE DOS ÁRBOLES BINOMIALES DE IGUAL GRADO. ............................................................. 10
21.12. MEZCLA DOS LISTAS ORDENADAS POR CAMPO GRADO. ............................................................... 10
21.13. MEZCLA DOS COLAS BINOMIALES. ............................................................................................... 11
21.14. INSERTAR..................................................................................................................................... 13
21.15. DESCARTAR. ................................................................................................................................ 13
21.16. EXTRACCIÓN DEL MÍNIMO. .......................................................................................................... 14
21.17. REVERSAR LISTA. ........................................................................................................................ 14
21.18. BUSCA MÍNIMO. ........................................................................................................................... 15
21.19. LISTA DE RAÍCES DE ÁRBOLES BINOMIALES. ................................................................................ 15
21.20. TEST DE LAS FUNCIONES. ............................................................................................................. 16
REFERENCIAS. ........................................................................................................................................ 16
ÍNDICE GENERAL. ................................................................................................................................... 17
ÍNDICE DE FIGURAS................................................................................................................................. 17
Índice de figuras.
FIGURA 21.1. DEFINICIÓN INDUCTIVA DE ÁRBOL BINOMIAL. ........................................................................ 1
FIGURA 21.2. EJEMPLOS DE ÁRBOLES BINOMIALES. ...................................................................................... 1
FIGURA 21.3. NUMERACIÓN BINARIA EN PREORDEN DE B3. .......................................................................... 2
FIGURA 21.4. NODO CON PROFUNDIDAD K EN BP. ......................................................................................... 2
FIGURA 21.5. SUBÁRBOLES DE B3. ................................................................................................................ 3
FIGURA 21.6. MULTIÁRBOLES BINOMIALES: B3 , B2, B1 , B0. ......................................................................... 5
FIGURA 21.7. REPRESENTACIÓN MEDIANTE LISTAS. ..................................................................................... 6
FIGURA 21.8. FORESTA CON 3 ELEMENTOS. .................................................................................................. 6
FIGURA 21.9. FORESTA CON 6 Y 7 ELEMENTOS. ............................................................................................ 7
FIGURA 21.10. GENERACIÓN DE B3 MEDIANTE MEZCLAS. ............................................................................. 7
FIGURA 21.11. REPRESENTACIÓN HIJO IZQUIERDO-HERMANO DERECHO DE B2 Y B3. .................................... 8
FIGURA 21.12. FORESTA CON 13 NODOS. LISTA DE RAÍCES........................................................................... 8
Profesor Leopoldo Silva Bijit
20-01-2010
18
Estructuras de Datos y Algoritmos
FIGURA 21.13. ENLACE DE DOS ÁRBOLES DE GRADO 2. ...............................................................................10
Profesor Leopoldo Silva Bijit
20-01-2010