You are on page 1of 19

Alumna: Alicia Snchez

Centro: UNED-Las Rozas (Madrid)




Ejercicios resueltos de programacin 3

Tema 5. Estructuras de datos.
























Ejercicios tema 5 Curso 2007-08 Pgina 2 de 19

Los ejercicios de este tema no son muchos, no obstante veremos el ndice como en el resto de
temas. Al no existir problemas de este tema, pondremos un nuevo apartado en el que habr
distintas cuestiones sin solucin.
1. Introduccin terica . 3
2. Cuestiones de exmenes 5
































Ejercicios tema 5 Curso 2007-08 Pgina 3 de 19

Introduccin terica:
Veremos estas nociones de teora correspondiente con los montculos, ya que es muy
importante el tenerlo claro, habiendo multitud de ejercicios que se resuelven de esta manera,
aunque luego insistamos de nuevo con esta misma teora en los ejercicios:

Es importantsimo tener bien claro la propiedad del montculo:
El nodo i es el padre de ]
2 i
2 i +1
.
El nodo i es el hijo del nodo i div 2 (o i 2).

En resumen y para los vectores sera:
_
I[i] I[2 i]
I[i] I[2 i +1]
_ Hijos con respecto a padres.
I[i] I[i Ji: 2]. Padres con respecto a hijos.

Relacionado con el ejercicio es que tenemos dos posibles algoritmos para crear un montculo.
El primero de ellos ser:
proc crear-montculo-lento(I[1..n])
para i 2 hasta n hacer flotar (I[1..i],i)
fproc
Para seguir el recordatorio veremos el algoritmo iterativo de flotar una posicin, que ser:
proc flotar (I[1..n],i)
k i;
repetir
] k;
si ] >1 y I[] 2] <I[k] entonces k ] 2
intercambiar I[]] y I[k]
{ si ] =k, entonces el nodo ha llegado a su posicin final }
hasta que ] =k
fproc

El segundo algoritmo ser el siguiente:
proc crear-montculo (I[1..N])
para i [n/ 2] bajando hasta 1 hacer hundir (I,i)
fproc
Vimos en la teora que uno de ellos es ineficiente con respecto a ello, lo que supone que hara
ms operaciones de flotar y aunque tiene coste lineal la constante multiplicativa es mayor.
Evidentemente, es el primero de ellos, lo cual no nos valdra para el ejercicio que queremos
resolver. Por tanto, escogeremos el algoritmo segundo que hemos escrito, ya que ser ms
eficiente.


Ejercicios tema 5 Curso 2007-08 Pgina 4 de 19

Pasamos a escribir el procedimiento para hundir un elemento del montculo:
proc hundir (I[1..n],i)
k i;
repetir
] k;
{ Buscar el hijo mayor del nodo j }
si 2 ] n y I[2 ]] >I[k] entonces k 2 ]
si 2 ] n y I[2 ] +1] >I[k] entonces k 2 ] +1
intercambiar I[]] y I[k]
{ si ] =k, entonces el nodo ha llegado a su posicin final }
hasta que ] =k
fproc
Estas funciones sern bastantes importantes el saberlos, ya que nos harn falta en numerosos
ejercicios. Por lo que sern de gran importancia el sabrselos (no memorizarlos, por supuesto).
Como regla nemotcnica (a m personalmente me vale) el hundir es ir de arriba abajo (como
los buzos) y flotar es ir de abajo a arriba. Es necesario el tener claro estas ideas, ya que son
crticas en los montculos.
Otra regla nemotcnica importante y que me ha liado mucho es asumir el significado de estas
variables:
i: Indica valor inicial que, dada por argumento, la posicin que se flota o hunde.
J: Indica la posicin que se refrescar tras intercambiar dentro del bucle repetir.
k: Indica la nueva posicin que asumir el elemento, previo al intercambio, igualmente
dentro del bucle repetir o ,dicho de otra manera, la posicin a la que se intercambiar el
elemento una vez que se cumple la propiedad del montculo bien sea con hundir o flotar.
Vemos que se sale del bucle cuando ] =k, por lo que ya no se podr intercambiar dos
posiciones.
Por ltimo, decir que siempre consideraremos montculos de mximos (la raz es el mximo
elemento), salvo cuando nos lo digan expresamente, ante ese caso tendremos montculos de
mnimos. No queda decir que las operaciones son las mismas, slo que cambian el signo.
La idea es considerar el vector como un montculo. Empezamos convirtiendo inicialmente en
montculos los subrboles del nivel ms bajo, para progresivamente seguir modificando en
niveles superiores sucesivos.











Ejercicios tema 5 Curso 2007-08 Pgina 5 de 19

1 parte. Cuestiones de exmenes:
Septiembre 2000-reserva (ejercicio 3)
Enunciado: Explicar cmo funciona el algoritmo que dota a un vector la propiedad del
montculo en tiempo lineal (no es necesario demostrar que ese es el coste).
Respuesta: Tenemos en mente los algoritmos vistos en la seccin de teora, siendo uno de
ellos ineficiente con respecto al otro, lo que supone que hara ms operaciones de flotar y
aunque tiene coste lineal la constante multiplicativa sera mayor. Evidentemente, es el primero
de ellos, lo cual no nos valdra para el ejercicio que queremos resolver. Por tanto, escogeremos
el algoritmo segundo que hemos escrito, ya que ser ms eficiente.
proc crear-montculo (I[1..N])
para i [n/ 2] bajando hasta 1 hacer hundir (I,i)
fproc
Veremos el funcionamiento con un ejemplo. Se nos da este vector I =[4,3,7,7,10,1]. En
forma de rbol ser:







Vemos que al ser el elemento en la posicin 2 no cumple la propiedad del montculo de
mximos, con lo que aplicaremos el procedimiento antes visto.
Tenemos estos pasos:
1
er
paso. Empezaremos por i =3, es decir, por la posicin 3 en el montculo.
Hacemos una llamada a hundir (I,3). Tendremos que hundir esta posicin para ordenarla.
Tendremos este subrbol:




Vemos, por tanto, que cumple la propiedad del montculo, en la que el padre es mayor o
igual que el hijo, por lo que no habr ningn intercambio de posiciones.
El vector no se modifica.





3
7
7 10 1
4
7
1
Ejercicios tema 5 Curso 2007-08 Pgina 6 de 19

2 paso. Continuaremos por i =2.
Haremos llamada a hundir (I,2). Veremos de nuevo el subrbol para as ver qu posicin
hay que hundir:





Observamos que el nodo padre es menor que los hijos por lo que NO cumple la propiedad
del montculo. Siguiendo el algoritmo hay que intercambiarlo con el hijo mayor, por lo que
intercambiamos estas posiciones:





Con lo que el resultado quedara as:





El vector tras este paso es I =[4,10,7,7,3,1].

3
er
paso. Seguimos por i =1 o lo que es lo mismo la raz.
Hacemos llamada a hundir (I,1). Nuestro subrbol ser:







Vemos que el nodo valor 4 (nuestra raz) es menor que cualquiera de sus hijos, por lo que a
priori no cumple la propiedad del montculo. Seguiremos la misma filosofa de antes e
intercambiamos con el hijo mayor, que de nuevo es la posicin del vector 2.

3
7 10
3
7 10
10
7 3
10
7
7 3 1
4
Ejercicios tema 5 Curso 2007-08 Pgina 7 de 19

Tras intercambiarlo, el montculo quedar:







Y el vector ser I =[10,4,7,7,3,1].
Vindolo de nuevo, observamos que sigue sin cumplirse la propiedad del montculo.
Nuestro algoritmo de hundir seguir por la posicin 2, que es la del ltimo intercambio.
Vemos, por tanto, que no cumple la propiedad del montculo de nuevo en dicha posicin,
por lo que se intercambia con el hijo mayor, como sigue:







El montculo resultante del intercambio ser:







En este caso, vemos que ya cumple la propiedad del montculo en todo el rbol. Por tanto,
ya se ha creado un montculo y el vector resultante ser:
I =[10,7,7,4,3,1].






4
7
7 3 1
10
4
7
7 3 1
10
7
7
4 3 1
10
Ejercicios tema 5 Curso 2007-08 Pgina 8 de 19

Ntese varios aspectos importantes:
- Al intercambiar con la posicin 2 observamos que el subrbol derecho se deja sin
explorar. Esto significa que ya cumple la propiedad previamente analizada en el
primer paso (cuando i =3).
- Hemos seguido el planteamiento utilizando rboles, pero tendremos presente que
una de las representaciones ms utilizadas es con vectores. Dicho esto, podramos
haber hecho esto mismo de forma grafica usando vectores y viendo as las
posiciones de intercambio.

Febrero 2001-1 (ejercicio 1)
Enunciado: Dado el siguiente montculo [10,6,3,5,2,3,2] se pide insertar el valor 6 describiendo
toda la secuencia de cambios en el mismo.
Respuesta: Tendremos el algoritmo de insercin siguiente:
proc aadir-nodo (I[1..n],:)
I[n +1] :;
flotar (I[1..n +1],n +1)
fproc
Observamos que se usa la funcin flotar (de abajo a arriba) para que al insertar el nuevo nodo
se recupere la propiedad del montculo. En nuestro caso, tenemos que aadir un nodo al
montculo [10,6,3,5,2,3,2].
Pasamos como en el ejercicio anterior el vector a un rbol:









El nuevo vector tras insertar el elemento es [10,6,3,5,2,3,2,6]
Resaltamos el nodo insertado en negrita. Vemos que habr que hacer una llamada a la funcin
flotar segn el procedimiento anterior, que ser flotar (I[1..8],8). Como antes, seguiremos
estos pasos, que se harn en la misma llamada de flotar (no confundir con el ejercicio anterior,
que eran distintas llamadas a las funciones).




6
3
5 2 3
10
2
6
Ejercicios tema 5 Curso 2007-08 Pgina 9 de 19

1. Se compara I[8] con su padre, que es I[8 II 2] =I[4]. Como es mayor se
intercambia resultando:








El vector, por el momento es [10,6,3,6,2,3,2,5].
2. Se comparar, en este caso, I[4] con su padre, que recordemos es I[4 II 2] =
I[2] y observamos que ambos son iguales. Por tanto, el bucle finalizar, al coincidir j
con k y ya ser montculo.

Febrero 2001-2 (ejercicio 3) (parecido a ejercicio 1 de Dic. 02)
Enunciado: Dado un montculo I[1..n], programar completamente en pseudocdigo una
funcin recursiva flotar (I,i) para flotar el elemento de la posicin i del vector T. Explicar
cmo usar esta funcin para insertar un elemento en el montculo.
Respuesta: Para realizar la primera parte del ejercicio tendremos que recordar el algoritmo
iterativo de flotar:
proc flotar (I[1..n],i)
k i;
repetir
] k;
si ] >1 y I[] 2] <I[k] entonces k ] 2
intercambiar I[]] y I[k]
{ si ] =k, entonces el nodo ha llegado a su posicin final }
hasta que ] =k
fproc
Por lo que, casi siendo una trascripcin directa tendremos el algoritmo recursivo de flotar:
proc flotar-rec (I[1..n],i)
si (i >1) and (I[i] >I[i II 2]) entonces
intercambiar I[i] y I[i II 2]
flotar-rec (I,i II 2)
fsi
fproc
La segunda parte de este ejercicio es exactamente igual al anterior, por lo que evitamos dar
ms detalles del mismo.

6
3
6 2
3 2
5
10
Ejercicios tema 5 Curso 2007-08 Pgina 10 de 19

Febrero 2002-1 (ejercicio 3) (Igual a ejercicio 2 Sept. 01-reserva)
Enunciado: Programar en pseudocdigo un algoritmo recursivo para la operacin de hundir un
elemento en un montculo.
Respuesta: Tendremos al igual que en el ejercicio anterior que partir del algoritmo iterativo de
hundir. Recordamos, de nuevo, que es:
proc hundir (I[1..n],i)
k i;
repetir
] k;
{ Buscar el hijo mayor del nodo j }
si 2 ] n y I[2 ]] >I[k] entonces k 2 ]
si 2 ] n y I[2 ] +1] >I[k] entonces k 2 ] +1
intercambiar I[]] y I[k]
{ si ] =k, entonces el nodo ha llegado a su posicin final }
hasta que ] =k
fproc
Intentaremos razonar de modo similar a como hemos hecho en el algoritmo recursivo de
flotar, pero nos topamos con un inconveniente, por el que tendremos que averiguar cul de
los dos hijos es el mayor, es decir, el de mayor valor, por lo que deberemos almacenar en una
variable temporal el valor del primero hijo para compararlo con el segundo e intercambiar el
mayor. Veamos de modo prctico esta explicacin previamente.
proc hundir-rec (I[1..n],i)
moyor i;
{ Buscar el hijo mayor del nodo i }
si (2 i n) y (I[2 i] >I[moyor]) entonces
moyor =2 i;
fsi
si (2 i +1 n) y (I[2 i +1] >I[moyor]) entonces
moyor =2 i +1;
fsi
{ Si cualquier hijo es estrictamente mayor que el padre }
si (moyor >i) entonces
intercambiar I[i] y I[moyor]
hundir-rec (I,moyor)
fsi
fproc

Febrero 2002-1 (ejercicio 3)
Enunciado: Programar en pseudocdigo todos los procedimientos necesarios para fusionar dos
conjuntos implementados con montculos. Suponer que los conjuntos no pueden tener
elementos repetidos.
Respuesta: Este ejercicio no tengo ni idea de cmo se puede resolver, slo s que pueden
pedir los cdigos que se han visto en teora de los montculos, pero en este caso piden fusionar
dos conjuntos implementados con montculos, lo cual desconozco. He buscado en internet, en
el libro, en muchos sitios ms que solucin tiene este ejercicio y no he podido llegar a ninguna
conclusin.
Ejercicios tema 5 Curso 2007-08 Pgina 11 de 19

Diciembre 2003 (ejercicio 2)
Enunciado: Qu diferencias hay entre un montculo y un rbol binario de bsqueda?
Respuesta: Para responder a esta pregunta vamos a definir que es cada uno de ellos y as se
ver ms adecuadamente sus diferencias. No hay solucin oficial de esta pregunta, por lo que
se ha tomado apuntes del libro base casi directamente (Fundamentos de Algoritmia de G.
Brassard y P. Bratley). Pasamos, pues, a las definiciones y a continuacin a las diferencias:
Un rbol de bsqueda es aqul en el que el valor contenido en todos los nodos internos es
mayor o igual que los valores contenidos en su hijo izquierdo o en cualquiera de los
descendientes de ese hijo y menor o igual que los valores contenidos en su hijo derecho o en
cualquiera de los descendientes de ese hijo.
El montculo es un rbol binario esencialmente completo, cada uno de cuyos nodos incluye un
elemento de informacin denominado valor del nodo y que tiene la propiedad consistente en
que el valor de cada nodo interno es mayor o igual que los valores de sus hijos. Esto se llama
propiedad del montculo.
Al eliminar o aadir nodos al rbol binario de bsqueda se puede volver desequilibrado, con lo
que muchos nodos pueden tener un solo hijo, as que sus ramas se vuelven largas y delgadas.
No resulta eficiente hacer bsquedas en el rbol desequilibrado, ya que el coste es lineal,
porque hay que recorrer todos los nodos. Para equilibrarlo requiere un coste de 0(logn), en
el caso peor, siendo n el nmero de nodos que hay en el rbol.
Al igual que pasa con el rbol de bsqueda al quitar nodos o aadirlos en un montculo hay
que restaurar la propiedad del montculo, lo que implica hundir o flotar, cuyo coste es
0(logn).
Observamos cmo hemos puesto en ocasiones anteriores que tomaremos la cota superior, en
vez del coste exacto, esto lo haremos porque al fin y al cabo el coste exacto es una unin de
cota superior y cota inferior. En el montculo ser coste exacto, pero lo dejaremos as.

Septiembre 2004 (ejercicio 2)
Enunciado: Implementar una versin recursiva de una funcin que tome un vector y le d
estructura de montculo.
Resultado:
Tendremos que hacer la versin recursiva de crear montculo. Hemos tomado de nuevo la
solucin que ponen (no sabemos si es oficial o no) con algunas modificaciones propias, aunque
nos fijamos que el algoritmo que han tomado es el de crear montculo lento, en el que hay
ms llamadas.
Recordemos la funcin iterativa de crear montculo:
proc crear-montculo-lento (I[1..n])
para i 2 hasta n hacer flotar (I[1..i],i)
fproc





Ejercicios tema 5 Curso 2007-08 Pgina 12 de 19

La funcin recursiva de crear montculo ser, por tanto, la siguiente:
proc crear-montculo-rec (I[1..n],i)
si i >n entonces
devuelve (I)
si no
flotar (I,i)
crear-montculo-rec (T, i+1)
fsi
fproc
Escribiremos la funcin recursiva de flotar, aunque lo hemos escrito previamente. Es otra
solucin posible, por lo que es interesante tenerla en cuenta:
proc flotar-rec (I[1..n]:tipo monticulo,VAR i:integer)
VAR i_padre: integer;
i_padre =i div 2;
si (i >1) and I[i] >I[i_poJrc] entonces
intercambiar I[i] y I[i_poJrc]
flotar-rec (I,i _poJrc)
fsi
fproc
La llamada inicial de la funcin de creacin de montculo ser:
crear-montculo-rec (I,2)
Otra versin es sin usar funciones auxiliares es sustituir el cdigo de flotar por ser versin
iterativa e insertarla en la funcin anterior.

Septiembre 2004-reserva (ejercicio 2)
Enunciado: Sea I[1..12] una matriz tal que I[i] =i para todo i 12. Crear un montculo en
tiempo lineal, especificando cada paso y mostrando en todo momento el estado de la matriz T.
Resultado:
Hemos visto en ejercicios anteriores los distintos algoritmos con los que se resuelven estos
ejercicios, por tanto, resolveremos el problema especificando paso a paso:

Inicialmente, el montculo ser:









2
3
4
5 6 7
8
1
10 9 11 12
Ejercicios tema 5 Curso 2007-08 Pgina 13 de 19

1
er
paso: Empezaremos por la mitad del montculo, es decir, con i =6:








Intercambiamos la posicin 6 con la 12, porque al usar el algoritmo de crear montculo rpido,
hundiremos (en vez de flotar).

2 paso: Seguiremos por i =5:









En este caso, intercambiaremos el valor de 5 con el hijo mayor, que es 11. En este caso, por el
momento, coincidirn las posiciones con los valores.










2
3
4
5
6
7
8
1
10 9 11 12
2
3
4
5
7
8 10 9 11 6
12
1
Ejercicios tema 5 Curso 2007-08 Pgina 14 de 19

3
er
paso: Seguiremos con i =4, que ser el valor 4 y se nuevo hundimos ese valor hasta que
cumpla la propiedad del montculo en el rbol:









Intercambiaremos de nuevo con el hijo mayor, que es 9.

4 paso: Nos vamos a i =3 y observamos en el grafo anterior que tendremos que
intercambiarlo con la posicin 6, es decir, el valor 12. Tendremos, por tanto,









De nuevo, vemos que al intercambiarlo no se cumple la propiedad del montculo, por lo que de
nuevo intercambiamos 3 con 6 (posicin 6 con la 12, al tener solo un hijo). Lo haremos en la
misma llamada a hundir, mucho cuidado con eso.








2
3
4
11 7
8 10 9 5 6
12
1
2
12
4
11 7
8 10 9 5 6
3
1
Ejercicios tema 5 Curso 2007-08 Pgina 15 de 19

5 paso: El penltimo paso ser aquel en que i =2.









Intercambiaremos la posicin 2 con la 5, que es su hijo mayor, resultando:









Al igual que el paso anterior necesitaremos hundir de nuevo este valor intercambiado, por lo
que ser la posicin 5 con la 10, su hijo mayor.

6 paso y ltimo: Estamos en i =1, que es el nodo raz, por lo que tendremos que ver este
rbol:








Intercambiaremos la posicin 1 con la 3 (el valor 1 con el 12), quedando:
2
12
4
11 7
8 10 9 5 3
6
1
11
12
4
2 7
8 10 9 5 6
3
1
11
12
4
10 7
8 2 9 5 6
3
1
Ejercicios tema 5 Curso 2007-08 Pgina 16 de 19









Vemos de nuevo que no cumple la propiedad del montculo, por lo que intercambiaremos la
posicin 3 con la 7 (el valor 1 con el 7), quedando el montculo completamente creado as:









No hemos puesto los vectores intermedios tras hundir los elementos, pero pondremos el
vector final, que ser [12,11,7,4,2,3,1,8,9,10,5,6].














11
1
4
2 7
8 10 9 5 6
3
12
11
7
4
2 1
8 10 9 5 6
3
12
Ejercicios tema 5 Curso 2007-08 Pgina 17 de 19

Septiembre 2005-reserva (ejercicio 1)
Enunciado: Dado m =[2,6,4,12,7,4,4]. Comprobar si es o no montculo de mnimos. Si no lo
es, programar una funcin para convertirlo en montculo y aplicarlo a m. Si no, programar
una funcin de aadir elemento mediante la funcin flotar y aplicarlo al valor 3. En ambos
casos, escribir el montculo resultante y detallar todos los pasos.
Resultado:
Verificaremos si es montculo de mnimos, que recordemos que es aqul en el que la raz es el
menor elemento. Tendremos en forma de rbol lo siguiente:







Verificaremos que cumple la propiedad del montculo en todo ello, que ser
_
I[i] I[2 i]
I[i] I[2 i +1]
_ Hijos con respecto a padres.
I[i] I[i Ji: 2]. Padres con respecto a hijos.
Observaremos que cumple la propiedad del montculo en todo el rbol. Por tanto, ya es
correcto.

Aadimos un elemento al final del montculo. Recordemos el algoritmo de aadir-nodo:
proc aadir-nodo (I[1..n],:)
I[n +1] :;
flotar (I[1..n +1],n +1)
fproc
En nuestro caso, variaremos conforme al montculo de mnimos la funcin flotar, como sigue:
proc flotar (I[1..n],i)
k i;
repetir
] k;
si ] >1 y I[] 2] >I[k] entonces k ] 2
intercambiar I[]] y I[k]
{ si ] =k, entonces el nodo ha llegado a su posicin final }
hasta que ] =k
fproc



6
4
12 7 4 4
2
Ejercicios tema 5 Curso 2007-08 Pgina 18 de 19

Al aadir el elemento 3, tendremos este rbol, para convertirlo en montculo:









Observamos como en los ejercicios anteriores, que no cumple la propiedad del montculo, por
lo que hay que flotar ese elemento (de abajo a arriba, ojito). Haremos estos pasos:

1 paso. Intercambiamos 3 con 12 (posicin 8 con 4):









De nuevo no cumple la propiedad del montculo, por lo que tendremos que hacer otro paso
ms.











6
4
12 7 4 4
2
3
6
4
3 7 4 4
2
12
Ejercicios tema 5 Curso 2007-08 Pgina 19 de 19

2 paso. Intercambiamos 3 con 6 (posicin 4 con 2):









Vemos que al acabar esta llamada a flotar ya queda restaurada la propiedad del montculo en
todo el rbol, por lo que se da por finalizado el ejercicio.

Febrero 2008-2 (ejercicio 2)
Enunciado: Sea I[1..n] con k elementos (k <n) un montculo de mnimos. Se pide programar
una funcin flotar que dado un nuevo elemento I[k +1] restaure la propiedad del
montculo en T. Una funcin iterativa que lo resuelva puntuar cero puntos.
Respuesta:
Tendremos la siguiente funcin que se asemeja enormemente a la dada en el ejercicio 3 de
Febrero de 2001-2 semana. Lo vamos a tratar, ya que es interesante verlo con ms calma:
proc flotar-rec (I[1..n]:tipo monticulo,VAR i:integer)
VAR i_padre: integer;
i_padre =i div 2;
si (i >1) and I[i] <I[i_poJrc] entonces
intercambiar I[i] y I[i_poJrc]
flotar-rec (I,i _poJrc)
fsi
fproc
Nos fijamos que con respecto a los algoritmos antes puestos, slo cambiar en el signo >,
puesto antes y ahora al ser un montculo de mnimos ser <.



3
4
6 7 4 4
2
12

You might also like