Vous êtes sur la page 1sur 15

1

Captulo 18

Pagodas. Seleccionar.
Una pagoda es una representacin de un rbol binario tal que los hijos tienen claves mayores o
iguales a las del padre. Es un algoritmo de seleccin que puede agregar tems en forma
dinmica, a diferencia del heap implcito, rbol binario embebido en un arreglo, que utiliza
memoria esttica.

18.1. Propiedades.
Cada nodo s de una pagoda contiene dos punteros i(s) y d(s) definidos como sigue:
(1) si s es la raz o es un hijo derecho: i(s) apunta al nodo ms izquierdista del subrbol de raz s.
(2) si s es un hijo izquierdo, i(s) apunta al padre de s.
El puntero d(s) est definido de una manera simtrica:
(1) si s es la raz o es un hijo izquierdo d(s) apunta al nodo ms derechista del subrbol de raz s.
(2) si s es un hijo derecho, d(s) apunta al padre de s.
Si se aplican las propiedades anteriores al rbol binario de prioridad, a la izquierda de la Figura
18.1, se obtiene la pagoda que se muestra a la derecha, de la misma Figura.
1

6
9

Figura 18.1. rbol de prioridad y Pagoda equivalente.


Una pagoda es un edificio de varios niveles, comn en pases asiticos. La Figura 18.1, a la
derecha adopta una forma similar a una pagoda, que se muestra en la Figura 18.2, por esto el
nombre.

Profesor Leopoldo Silva Bijit

20-01-2010

Estructuras de Datos y Algoritmos

Figura 18.2. Pagodas.

18.2. Listas circulares de la raz de una pagoda.


Sin embargo si se redibuja la Figura 18.1, a la derecha, segn un rbol binario convencional, se
advierten dos listas circulares asociadas a la raz; una formada por los punteros derechos del
subrbol derecho; y otra formada por los punteros izquierdos del subrbol izquierdo. Esto se
ilustra en la Figura 18.3. A partir de la raz, las listas estn en orden descendente, y los
elementos menores de estas listas apuntan a la raz. Si se desea eliminar la raz, deben
modificarse esas dos direcciones.
1

2
8

Figura 18.3. Pagoda y sus listas circulares principales.


Cada nodo puede considerarse la raz de una pagoda, que debe cumplir las propiedades que la
definen, para los descendientes de ese nodo. Por ejemplo, en el nodo con valor 2, se tiene una
pagoda que tiene lista circular izquierda nula; en forma similar las pagodas asociadas a los
nodos 8 y 3 pueden considerarse formadas por un solo elemento.

18.3. Mezcla de pagodas.


La operacin bsica es la de mezclar o fundir (meld or merg), que puede definirse como unir
dos estructuras de datos, con determinadas propiedades, en una estructura mayor, que cumple la
misma propiedad.

Profesor Leopoldo Silva Bijit

20-01-2010

Colas de prioridad. Pagodas.

La insercin se logra mezclando una pagoda formada por un elemento con aquella en la que se
inserta el nuevo elemento. Esta forma de realizar la operacin cubre el caso en el cual el nuevo
elemento es el menor de todos.
n

Figura 18.3a. Pagoda con un elemento.


En el ejercicio E1, se propone otro algoritmo de insercin, aplicando la definicin de una
pagoda.
El descarte, remocin o seleccin de la raz, que tiene el valor de prioridad mnimo, va seguida
de la mezcla de las subpagodas izquierda y derecha de la raz.
stas se obtienen desplazando los elementos menores a la posicin de la nueva raz de las
subpagodas. Esto se muestra en la Figura 18.4, considerando que se descart la raz de valor 1,
en la Figura 18.3.
left
3

9
8

Figura 18.4. Subpagodas de la raz, de la Figura 18.3.


Si p apunta a la raz, y la pagoda izquierda es apuntada por left, el siguiente segmento determina
el puntero left, que define la subpagoda izquierda. Se tiene cdigo especular para obtener la
pagoda derecha.
if ( p->left == p ) left = NULL;
else
{ for ( left = p->left; left->left != p; left = left->left) ;
left->left = p->left;
};

18.4. Anlisis de la mezcla.


La mezcla de dos pagodas a y b, en rn, se realiza uniendo la lista circular izquierda de una
pagoda con la lista circular derecha de la otra.

Profesor Leopoldo Silva Bijit

20-01-2010

Estructuras de Datos y Algoritmos

En la Figura 18.5, se eligi la lista circular izquierda de la pagoda a la izquierda de la Figura


18.4. Se han abstrado los elementos que no forman parte de las listas circulares, empleando
pequeos tringulos para los descendientes.
Los cdigos de las funciones figuran en la segunda referencia, al final del captulo.
b
rn
4

a
3

Figura 18.5. Listas circulares de las pagodas que se desea mezclar.


Se recorren ambas listas en forma descendente, colocando en una nueva pagoda los elementos
de las listas circulares; es decir agregando el 7, luego el 5, despus el 4, a continuacin el 3, y
finalmente el 2. Se emplea rn para apuntar a la nueva pagoda en formacin.
Para recorrer las listas se emplean los punteros la y lb. El siguiente segmento inicia los punteros
a las listas circulares:
la = a->right;
a->right = NULL;
lb = b->left;
b->left = NULL;

//apunta al mayor de lista descendente derecha


// marca fin de lista derecha
//apunta al mayor de lista descendente izquierda
// marca fin de lista izquierda

rn = NULL;

//forma nueva pagoda con raz rn


b

rn
2

lb

a
3

la

Figura 18.6. Inicio de listas circulares descendentes.


Si como en el caso del ejemplo, el elemento mayor se encuentra en la lista derecha, el siguiente
cdigo va formando la nueva pagoda:
t = la->right;
if ( rn==NULL ) la->right = la; // pagoda con un elemento. Padre de s mismo
else
{ la->right = rn->right;
//apunta al mayor de lista derecha
Profesor Leopoldo Silva Bijit

20-01-2010

Colas de prioridad. Pagodas.

rn->right = la;
//cierra lista circular
};
rn = la;
//la raz siempre apunta al menor
la = t;
//avanza por la derecha
Despus de ejecutado el segmento anterior, del cual se ejecuta el if, la Figura 18.7, muestra la
situacin:
rn
7

a
la

Figura 18.7. Despus de insertado el 7.


Si se vuelve a repetir el cdigo anterior, se ejecutar el else, y luego de ste se tiene la Figura
18.8.
t

rn

la

Figura 18.8. Despus de insertado el 5, luego del else.


El segmento finaliza actualizando la nueva pagoda, que incluye al 7 y al 5. Se muestra ahora el
tringulo rojo descendiente del 5, expandido, de acuerdo a la Figura 18.4. Ntese que no se
alteran los punteros de los elementos del tringulo rojo.
la

rn

3
8

Figura 18.9. Despus de insertado el 5.


De acuerdo a la Figura 18.6, ahora debe agregarse el nodo 4, que pertenece a la lista circular
izquierda, ya que es mayor que el nodo que an resta considerar en la lista circular derecha. Para
esto debe ejecutarse el cdigo especular del anterior:

Profesor Leopoldo Silva Bijit

20-01-2010

Estructuras de Datos y Algoritmos


t = lb->left;
if ( rn==NULL ) lb->left = lb;
else { lb->left = rn->left;
rn->left = lb;
};
rn = lb;
lb = t;

Luego de la ejecucin, la nueva pagoda, se muestra a la izquierda en la Figura 18.10. Luego se


repite el proceso en la lista derecha para agregar el nodo 3.
rn
3

rn
4

5
7

Figura 18.10. Formacin de pagodas, despus de agregar los nodos: 4, 3.


Habindose agotado la lista circular derecha, es preciso finalizar la pagoda agregando el resto de
la lista circular izquierda, esto puede lograrse, con el siguiente segmento:
b->left = rn->left;
rn->left = lb;
b

lb
2

Figura 18.11. Resto de lista circular izquierda.


Finalmente, despus de agregar el nodo con valor 2 y su descendencia derecha, donde el
tringulo se ha reemplazado por su equivalente, de acuerdo a la Figura 18.4, se tiene la Figura
18.12, la pagoda queda apuntada por b.
Si se termina primero la lista circular izquierda, debe ejecutarse el cdigo especular:
a->right = rn->right;
rn->right = la;

Profesor Leopoldo Silva Bijit

20-01-2010

Colas de prioridad. Pagodas.

Quedando, en este caso, la pagoda apuntada por a.


b
2
3

8
5
7

Figura 18.12. Mezcla de las pagodas de la Figura 18.4.

18.5. Definicin de tipos.


Se tiene la siguiente definicin para la estructura del nodo:
typedef struct bintree
{ int prioridad;
struct bintree * left;
struct bintree * right;
} nodo, *pnodo ;

18.6. Creacin de nodo.


pnodo getnodo(int dato)
{ pnodo p=NULL;
if ( (p= (pnodo) malloc(sizeof(nodo))) ==NULL)
{ printf("Error: Memoria. \n"); exit(1);}
else
{ //forma pagoda de un elemento
p->prioridad=dato; p->left=p; p->right=p;
}
return(p);
}

18.7. Funcin mezclar.


La funcin completa para la mezcla de dos pagodas a y b, contempla los casos particulares en
los cuales una de las pagodas es nula.

Profesor Leopoldo Silva Bijit

20-01-2010

Estructuras de Datos y Algoritmos

pnodo merge( pnodo a, pnodo b )


{pnodo la, lb, rn, temp;
if ( a==NULL ) return( b );
else if ( b==NULL ) return( a );
else
{la = a->right;
//En pagoda a, la apunta al mayor de lista descendente derecha
a->right = NULL; // marca fin de lista derecha
lb = b->left; //En pagoda b, lb apunta al mayor de lista descendente izquierda
b->left = NULL; // marca fin de lista izquierda
rn = NULL; //forma nueva pagoda con raz rn
/*** Merging loop ***/
while ( la!=NULL && lb!=NULL )
if ( la->prioridad > lb->prioridad ) //mantiene el de menor prioridad en la raz
{ temp = la->right; //colocando en la nueva pagoda primero el mayor de ambas listas.
if ( rn==NULL ) la->right = la; // pagoda con un elemento. Padre de s mismo
else
{ la->right = rn->right;
//apunta al mayor de lista derecha
rn->right = la;
//cierra lista circular
};
rn = la;
//apunta al menor
la = temp;
//avanza por la derecha
}
else //especular
{ temp = lb->left;
if ( rn==NULL ) lb->left = lb;
else
{ lb->left = rn->left;
rn->left = lb;
};
rn = lb;
lb = temp;
};
/*** Si se termina una de las listas circulares, se agrega el resto de la otra ***/
if ( lb==NULL )
{ a->right = rn->right;
rn->right = la;
return( a );
}
else //la==NULL especular
{ b->left = rn->left;
rn->left = lb;
return( b );
}
}
}

Profesor Leopoldo Silva Bijit

20-01-2010

Colas de prioridad. Pagodas.

18.8. Descartar.
pnodo descartar( pnodo pq )
{
pnodo le, ri;
if ( pq==NULL ) {printf("Error: Descarte en pagoda vaca.\n"); return(NULL);}
else
{ /*** Encuentra le descendiente izquierdo de pq ***/
if ( pq->left == pq ) le = NULL;
else
{ le = pq->left;
while ( le->left != pq ) le = le->left;
le->left = pq->left;
};
/*** Encuentra ri descendiente derecho de pq ***/
if ( pq->right == pq ) ri = NULL;
else
{ ri = pq->right;
while ( ri->right != pq ) ri = ri->right;
ri->right = pq->right;
};
/*** mezcla pagodas ***/
//Debera usarse el elemento obtenido.
printf("%d ", pq->prioridad);
//Modo debug: el que se saca se imprime
free(pq);
return( merge( ri, le ) );
}
}

18.9. Insertar.
pnodo insertar( pnodo pq, int valor )
{ //forma pagoda con un elemento
pnodo nuevo=getnodo(valor);
return( merge( pq, nuevo ) );
}
Si se introducen los valores de los nodos en forma ascendente, se produce una lista circular
izquierda con todos los nodos menos la raz, y una derecha vaca. La pagoda degenera en una
lista circular. En este caso el costo de insertar n tems es O(n), ya que en cada insercin se
realiza una vez el ciclo while de la funcin mezclar; y el descarte es O(1), ya que una de las
listas circulares es vaca y no se ejecuta el ciclo while de la funcin mezclar.
En el ejercicio E1, se muestra un diseo alternativo de la insercin en una pagoda, la cual se
construye aplicando las propiedades de una pagoda, sin implementar en base a la operacin
mezclar.

Profesor Leopoldo Silva Bijit

20-01-2010

10

Estructuras de Datos y Algoritmos

18.10. Mostrar listas circulares de la raz de una pagoda.


int prtpagoda(pnodo p)
{ pnodo t;
if (p!=NULL) printf("rn=%d ri->", p->prioridad);
else {printf("Pagoda nula\n"); return (0);}
for(t=p->right; t!=NULL && t!=p; t=t->right) printf("%d ", t->prioridad);
printf(" le->");
for(t=p->left; t!=NULL && t!=p; t=t->left) printf("%d ", t->prioridad); putchar('\n');
return(1);
}

18.11. Test de las funciones.


pnodo pagoda=NULL;
srand(1); //se generan 20 claves aleatorias.
for(i=0; i<20; i++) pagoda=insertar(pagoda, rand()%100);
prtpagoda(pagoda);
for(i=0; i<20; i++) pagoda=descartar(pagoda);
putchar('\n');
prtpagoda(pagoda);
Lo cual genera:
rn=12 ri->22 17 le->51 32
12 17 22 25 32 43 48 50 51 54 58 61 69 80 81 82 97 97 98 98
Pagoda nula
Ntese que la funcin descartar, va imprimiendo los valores de los tems seleccionados, de
menor a mayor. El ciclo while de mezclar se repite 34 veces para la insercin de los 20 items, y
37 veces para descartarlos; esta cuenta es fcil de obtener agregando un contador de las veces
que se ejecuta el lazo de mezcla. Ntese que para 20 tems, resultan en este caso aleatorio listas
circulares de largo dos.

Ejercicios.
E18.1.
Verificar que la siguiente funcin inserta en una pagoda, cuya direccin es pasada por
referencia.
void enqueue(pnodo *r, int valor)
{ pnodo p, q=*r, n=getnodo(valor);
if (q==NULL) *r=n; //pagoda nula, insercin trivial
else
{ p=q->right;
Profesor Leopoldo Silva Bijit

20-01-2010

Colas de prioridad. Pagodas.

11

if(valor >= p->prioridad) // nuevo al inicio lista derecha


{ n->right=q->right;
q->right=n;
}
else if (valor<=q->prioridad) //reemplaza raz en fondo lista izquierda
{ n->left=q->left;
q->left=n;
*r=n;
}
else //hay que recorrer la lista
{ while(valor < p->right->prioridad) p=p->right;
n->right=p->right; //pega al nuevo el descendiente derecho
p->right=q->right; //pega inicio de lista de q en p
q->right=n; //acorta lista derecha
n->left=p->left; //resto de lista derecha la pega a la izquierda del nuevo
p->left=n;
}
}
} /* enqueue */
E18.2.
Verificar que la siguiente funcin retorna un puntero al nodo con valor mnimo, en una pagoda,
cuya direccin es pasada por referencia.
pnodo dequeue( pnodo * q )
{
pnodo lb, rb, f, t, dequeue_result;
dequeue_result = *q;
lb = (*q)->right;
rb = (*q)->left;
if (lb == rb) { /* Hay un solo nodo en la pagoda */
*q = NULL;
} else if (lb == *q) {
/* no hay descendiente derecho */
do { rb = rb->left; } while (!(rb->left == *q));
rb->left = (*q)->left;
*q = rb;
} else if (rb == *q) {
/* no hay descendiente izquierdo. especular */
do { lb = lb->right;} while (!(lb->right == *q));
lb->right = (*q)->right;
*q = lb;
} else {
/* descarte no trivial */
/* compara hijos izquierdo y derecho, prepara mezcla de sub-pagodas */
if (lb->prioridad >= rb->prioridad) {
f = lb;
t = lb->right;
lb->right = lb;
Profesor Leopoldo Silva Bijit

20-01-2010

12

Estructuras de Datos y Algoritmos


lb = t;
} else { //especular
f = rb;
t = rb->left;
rb->left = rb;
rb = t;
}
/* mezcla ramas izquierda y derecha, desde el fondo hasta el tope */
while ((lb != *q) && (rb != *q)) {
if (lb->prioridad >= rb->prioridad) {
t = lb->right;
lb->right = f->right;
f->right = lb;
f = lb;
lb = t;
} else { //especular
t = rb->left;
rb->left = f->left;
f->left = rb;
f = rb;
rb = t;
}
}
/* Coloca lo que quedo de la mezcla en el tope de la cola */
if (lb == *q) {
t = f->left;
f->left = rb;
while (rb->left != *q) { rb = rb->left; }
rb->left = t;
*q = rb;
} else { //especular
t = f->right;
f->right = lb;
while (lb->right != *q) {lb = lb->right;}
lb->right = t;
*q = lb;
}

}
return dequeue_result;
} /* dequeue */
Luego de usar el nodo, debera liberarse el espacio asociado al nodo.

Profesor Leopoldo Silva Bijit

20-01-2010

Colas de prioridad. Pagodas.

13

E18.3.
Verificar que las siguientes funciones implementan una cola de prioridad empleando una lista
simplemente enlazada, ordenada por el valor de prioridad.
typedef struct lista
{ int prioridad;
struct lista * proximo;
} nlista, *plista ;
plista getlista(int dato)
{ plista p=NULL;
if ( (p= (plista) malloc(sizeof(nlista))) ==NULL)
{ printf("Error: Memoria lista. \n"); exit(1);}
else { p->prioridad=dato; p->proximo=NULL; }
return(p);
}
//encola ordenado por prioridad.
//prioridades iguales en orden de llegada. Estable
plista encola (plista *p, int k )
{ plista p1, p2, p3;
if (*p==NULL)
{p1=getlista(k); *p=p1; return(p1);}
else
for( p2 = NULL, p1 = *p; p1 != NULL && p1->prioridad <=k; p2 = p1, p1 = p1->proximo );
p3= (plista) malloc (sizeof (nlista)) ;
if(p3!=NULL)
{ p3->prioridad = k;
if (p2 == NULL) { /* inserta al inicio */
p3->proximo = p1;
*p=p3;
}
else
{ p3->proximo = p2->proximo;
p2->proximo = p3;
}
}
return p3 ;
}
//desencola en lista ordenada.
plista desencola(plista *q)
{ plista t=*q;
if (t!=NULL)
{*q=t->proximo; return (t);}
Profesor Leopoldo Silva Bijit

20-01-2010

14

Estructuras de Datos y Algoritmos

else return(NULL);
}
void prtcola(plista p)
{
for( ; p!=NULL; p=p->proximo)
printf( "%d ", p->prioridad);
putchar('\n');
}
E18.4.
Modificar las funciones para tener seleccin de mximo, en lugar de mnimo.

Referencias.
J. Francon, G. Viennot, and J. Vuillemin, Description and analysis of an efficient priority
queue representation, Proc. 19th Annual Symp. on Foundations of Computer Science. IEEE,
1978, pages 1-7.
Gaston H. Gonnet, R. Baeza-Yates, Handbook of Algorithms and Data Structures in Pascal
and C, Addison-Wesley Pub., May 1991.
Douglas W. Jones, An empirical comparison of priority queue and even-set implementations,
Communications of the ACM, April 1986 Volume 29 Number 4.

Profesor Leopoldo Silva Bijit

20-01-2010

Colas de prioridad. Pagodas.

15

ndice general.
CAPTULO 18 ........................................................................................................................................... 1
PAGODAS. SELECCIONAR. .................................................................................................................. 1
18.1. PROPIEDADES. ................................................................................................................................. 1
18.2. LISTAS CIRCULARES DE LA RAZ DE UNA PAGODA............................................................................ 2
18.3. MEZCLA DE PAGODAS. ..................................................................................................................... 2
18.4. ANLISIS DE LA MEZCLA. ................................................................................................................ 3
18.5. DEFINICIN DE TIPOS. ...................................................................................................................... 7
18.6. CREACIN DE NODO......................................................................................................................... 7
18.7. FUNCIN MEZCLAR. ......................................................................................................................... 7
18.8. DESCARTAR. .................................................................................................................................... 9
18.9. INSERTAR. ....................................................................................................................................... 9
18.10. MOSTRAR LISTAS CIRCULARES DE LA RAZ DE UNA PAGODA. ...................................................... 10
18.11. TEST DE LAS FUNCIONES. ............................................................................................................. 10
EJERCICIOS. ............................................................................................................................................ 10
E18.1. ................................................................................................................................................ 10
E18.2. ................................................................................................................................................ 11
E18.3. ................................................................................................................................................ 13
E18.4. ................................................................................................................................................ 14
REFERENCIAS. ........................................................................................................................................ 14
NDICE GENERAL. ................................................................................................................................... 15
NDICE DE FIGURAS................................................................................................................................. 15

ndice de figuras.
FIGURA 18.1. RBOL DE PRIORIDAD Y PAGODA EQUIVALENTE. ................................................................... 1
FIGURA 18.2. PAGODAS. .............................................................................................................................. 2
FIGURA 18.3. PAGODA Y SUS LISTAS CIRCULARES PRINCIPALES. ................................................................. 2
FIGURA 18.3A. PAGODA CON UN ELEMENTO. ............................................................................................... 3
FIGURA 18.4. SUBPAGODAS DE LA RAZ, DE LA FIGURA 18.3. ...................................................................... 3
FIGURA 18.5. LISTAS CIRCULARES DE LAS PAGODAS QUE SE DESEA MEZCLAR............................................. 4
FIGURA 18.6. INICIO DE LISTAS CIRCULARES DESCENDENTES. ..................................................................... 4
FIGURA 18.7. DESPUS DE INSERTADO EL 7. ................................................................................................ 5
FIGURA 18.8. DESPUS DE INSERTADO EL 5, LUEGO DEL ELSE. .................................................................... 5
FIGURA 18.9. DESPUS DE INSERTADO EL 5. ................................................................................................ 5
FIGURA 18.10. FORMACIN DE PAGODAS, DESPUS DE AGREGAR LOS NODOS: 4, 3...................................... 6
FIGURA 18.11. RESTO DE LISTA CIRCULAR IZQUIERDA................................................................................. 6
FIGURA 18.12. MEZCLA DE LAS PAGODAS DE LA FIGURA 18.4..................................................................... 7

Profesor Leopoldo Silva Bijit

20-01-2010

Vous aimerez peut-être aussi