Sei sulla pagina 1di 7

Mdulo 5

Manejo dinmico de memoria


(aplicacin de lista simplemente ligada)

Introduccin
Dentro de algunas aplicaciones es a veces necesario manejar nmeros enteros cuya
capacidad supera la que manejan los tipos predefinidos por los lenguajes de progra-
macin. Si, por ejemplo, se desea conocer exactamente la distancia al sol en milme-
tros, ninguna mquina de las actuales soportara esa cantidad de dgitos, por lo cual
debemos buscar una forma de representacin en la que podamos obtener dicha cifra
y adems hacer operaciones aritmticas con ella. En este mdulo presentaremos una
forma de hacerlo utilizando listas simplemente ligadas.
Desde la era primitiva el hombre busc
Objetivos siempre respuestas a sus inquietudes. La inquietud
1. Definir la forma de representar enteros usando la clase lista simplemente ligada. permiti la aparicin de conceptos abstractos en
2. Desarrollar algoritmos para manipular nmeros enteros bajo esta representacin. la mente del hombre primitivo ya evolucionado.
Cuando el hombre desarrolla la capacidad de darle
Preguntas bsicas sentido racional a las cosas, nace el concepto de can-
1. Cuntos dgitos se pueden almacenar por nodo para representar enteros en listas tidad. Inicialmente no utilizbamos la notacin ar-
simplemente ligadas? biga, sino que representbamos las cantidades con
2. Qu cuidado se debe tener para escribir un entero representado como lista ligada? marcas en los rboles, con un montn de piedras,
3. Por qu definimos la clase altaPrecisin derivada de la clase lista simplemente nudos en sogas, etc. Los recursos que utilizbamos
ligada? dependan de la cultura donde estbamos ubicados.
Diversas culturas representaban la nocin de canti-
Contenidos dad segn su desarrollo lo permita. Fruto de esta
5.1 Representacin diversidad nacen las notaciones de cantidad, como
5.2 Clase altaPresicion la romana, la babilnica, la griega, etc. Se sabe que
5.3 Suma de enteros de alta precisin
5.4 Escritura de un nmero de alta precisin
los babilonios utilizaron simples enteros positivos
para tratar de contar unas pocas ovejas, mientras
que hoy en da los enteros positivos no satisfacen el
complejo mundo de las matemticas. Desde luego,
el significado que cada grupo social asigna a un
determinado conocimiento o idea implica mucho
en su visin de vida. Por ejemplo, los pitagricos
tenan una explicacin de la realidad basada en los
nmeros. Filolao, filsofo pitagrico, resume perfec-
tamente el papel tan importante que se le otorgaba:
El nmero reside en todo lo que es conocido. Sin l
es imposible pensar nada ni conocer nada. La fa-
cultad de contar est implcita en la aparicin del
nmero. Se mencion que el hombre haca marcas,
aunque a veces los seguimos haciendo, para repre-
sentar ciertas cantidades, pues esta actividad, que
perdura desde tiempos inmemoriales, se formaliz
en cada cultura con el nmero. El hombre advirti
que todos los conjuntos de objetos o de seres 5.1 Representacin
tienen una cualidad en comn, con indepen- Definamos primero la forma como representaremos nmeros enteros de esta magnitud
dencia de la naturaleza de los objetos o de los utilizando listas simplemente ligadas. Si deseamos representar el siguiente nmero:
seres que lo componen. La cualidad se deno-
mina nmero. Un ejemplo prctico reside en 23546879510357954665795
que el hombre, al realizar tantas marcas, jun-
tar tantas piedras, hacer tantos nudos deduce usaremos una lista simplemente ligada almacenando de a cuatro dgitos por nodo, confor-
racionalmente, segn la contabilidad de cada mando los grupos de cuatro dgitos de derecha a izquierda. Nuestra lista queda as (figura
objeto, que dichas contabilidades conllevan 5.1):
a representaciones, que no depende de qu
estuviese contando, sino ms bien del nmero
primero 235 4687 9510 3579 5466 5795
de marcas, de piedras, de nudos, etc. Entonces
se estableci un smbolo para cada contabili-


ultimo
dad respectiva. La contabilidad de una oveja
Figura 5.1
se simbolizara con I, 1, etc., segn cada cul-
tura establezca ese smbolo como universal.
En general, se pueden almacenar 1, 2, 3 o cualquier otra cantidad de dgitos por nodo; sin
El nacimiento de los sistemas numricos tiene
embargo, hemos elegido 4 porque permite definir el dato almacenado en cada nodo como
como precedente esta sistematizacin de uni-
entero y manipularlo eficientemente.
versalidad. De ah la notacin que utilizamos
hoy en da, que en general fue traida de la In-
Teniendo definida la representacin, el siguiente paso ser desarrollar los programas ten-
dia a Europa por los rabes en el siglo X. Hasta
dientes a manipular los nmeros enteros de alta precisin bajo dicha representacin. Es
esta lnea hemos presentado la aparicin del
decir, algoritmos para sumar, restar, etc., nmeros enteros bajo esta representacin.
nmero. Sin embargo, todo aquello se debe a
la necesidad por la cual evolucionan las mate-
mticas; pues bien, tenemos que ingresar con 5.2 Clase altaPrecision
esto a la aparicin de dos grandes ideas en la Como hemos decidido representar nmeros enteros con muchos dgitos como lista ligada,
matemtica: el nmero natural y entero. La definiremos una clase llamada altaPrecision, la cual ser derivada de nuestra clase lista
matemtica evoluciona o cambia, para otros, simplemente ligada (LSL), lo cual implica que todo objeto definido de altaPrecision podr
segn el contexto lo permita para dar solucin hacer uso de todos los mtodos definidos para la clase LSL. Como queremos que los ob-
a problemas . jetos de la clase altaPrecision puedan acceder tambin los datos privados de la clase LSL,
definimos dichos datos como protegidos, en vez de privados. Los mtodos a desarrollar
Tomado de http://images.goo- sern:
gle.com.co/imgres?imgurl=http://bp3.
blogger.com/_Vr_F3dJTMmA/SAoDwI- Leer nmero
l3aKI/AAAAAAAAAAM/FFMDxbRiROA/ Escribir nmero
s320/arquimedes01%255B1%255D. Sumar dos nmeros
jpg&imgrefurl=http://matematicahume- Restar dos nmeros
nor.blogspot.com/2008/04/nmeros-ente- Multiplicar dos nmeros
ros-origen-e-historia.html&usg=__mv7Lz Dividir dos nmeros
O1VTNvnak4fEVmrpny9rxE=&h=320&w=2
85&sz=21&hl=es&start=112&itbs=1&tbn Definamos entonces nuestra clase altaPrecision.
id=GbLwzweHuSNW2M:&tbnh=118&tbnw
=105&prev=/images%3Fq%3Dnumeros% Clase altaPrecision derivada de LSL
2Benteros%2Bgrandes%26start%3D105%2 Pblico
6hl%3Des%26sa%3DN%26gbv%3D2%26n void leeNumero()
dsp%3D21%26tbs%3Disch:1 void escribeNumero()
altaPrecision sume(altaPrecision b)
altaPrecisin reste(altaPrecision b)
altaPrecisin multiplique(altaPrecision b)
altaPrecisin divida(altaPrecision b)
void evalue(entero d1, entero d2, entero acarreo)
fin(altaPrecision)

El mtodo leeNumero() aceptar como entrada una hilera de caracteres, la procesar y

|72 Ude@-Facultad de Ingeniera


Mdulo 5. Manejo dinmico de memoria (manejo de lista simplemente ligada)

construir una lista simplemente ligada, almacenando de a cuatro dgitos por nodo. En el
mdulo correspondiente a manejo de caracteres presentaremos este algoritmo.

El mtodo escribeNumero() imprimir el nmero representado en una lista.

Los mtodos para sumar, restar, multiplicar y dividir crearn una nueva lista en la cual se
tendr el resultado correspondiente a efectuar cada operacin con el objeto de llamada y
el objeto b entrado como parmetro.

5.3 Suma de enteros de alta precisin


Teniendo definida la clase altaPrecision podremos escribir un programa para manejar n-
meros de alta precisin usando los mtodos definidos para esta clase. Un programa podra
ser:

1. altaPrecision a, b, c
2. a = new altaPrecision()
3. b = new altaPrecision()
4. a.leeNumero()
5. b.leeNumero()
6. c = a.sume(b)
7. a.escribeNumero()
8. b.escribeNumero()
9. c.escribeNumero()

En este algoritmo definimos tres variables de la clase altaPrecision: se crean dos objetos
vacos, instrucciones 2 y 3; se construye la lista correspondiente a cada uno de esos nme-
ros, instrucciones 4 y 5; se crea un nuevo nmero (instruccin 6), el cual es la suma de los
nmeros ledos, usando el mtodo suma definido en nuestra clase; y por ltimo se escriben
los nmeros ledos y el resultado de la suma de ellos, instrucciones 7 a 9.

Ocupmonos ahora del algoritmo de sumar.

Si deseamos sumar 4358795 con 62759, en nuestra aritmtica decimal la suma se efecta
as:

4358795
62759
________
4421554

Es decir, comenzamos sumando primero los dgitos menos significativos (los dgitos ms
a la derecha) y nos movemos con ambos nmeros de derecha a izquierda teniendo en
cuenta si se lleva algn acarreo o no. Lo anterior implica que para poder efectuar la suma
con nuestra representacin debemos ubicarnos en el ltimo nodo de cada lista y luego
devolvernos en ellas simultneamente efectuando la suma del nmero contenido en cada
nodo, teniendo en cuenta el acarreo. Pero, como ya hemos visto anteriormente, las listas
simplemente ligadas que tenemos definidas slo se pueden recorrer en un solo sentido:
de izquierda a derecha.
Teniendo en cuenta esta restriccin debemos definir un mecanismo que nos permita
recorrer las listas simplemente ligadas en sentido inverso, o sea de derecha a izquierda.
Para lograr esto, lo que haremos ser reversar los apuntadores de la lista, es decir, el cam-
po de liga de cada nodo apuntar hacia el nodo anterior y no hacia el siguiente. Llamemos
este mtodo reversaLista(). El efecto de este algoritmo ser: si tenemos la siguiente lista
(figura 5.2):

Algoritmia II 73|
primero a 1 e 6 i 2 o 8 u
3 1 6 2 8


ultimo
Figura 5.2

y le aplicamos el algoritmo reversaLista(), la lista quedar as (figura 5.3):

a e 3 i 1 o 6 u 2 primero
3 1 6 2 8

ultimo
Figura 5.3

y podremos recorrerla de derecha a izquierda.

Ocupmonos ahora de elaborar el algoritmo correspondiente a dicho mtodo. Para lograr


este objetivo slo necesitamos conocer la direccin de tres nodos consecutivos que llama-
remos r, q y p, donde r apunta hacia el nodo anterior a q, q apunta hacia el nodo anterior
a p, y p es la variable con la cual iremos recorriendo la lista.

Esquemticamente tendramos la siguiente situacin (figura 5.4):



8 ... a e i o u



r q p

Figura 5.4

y el proceso de reversar apuntadores se efectuara con las siguientes instrucciones:

q.asignaLiga(r)
r=q
q=p
p = p.retornaLiga()

en las cuales la primera instruccin reversa el apuntador de q y en las tres siguientes se


avanza con r, q y p.

Entendiendo las anteriores instrucciones, el siguiente paso es incrustarlas dentro de un


ciclo de recorrido de la lista y habremos reversado los apuntadores de la lista.

Nuestro algoritmo ser:

void reversaLista()
nodoSimple p, q, r
p = primerNodo()
ultimo = p
q = anterior(p)
while (no finDeRecorrido(p)) do
r=q

|74 Ude@-Facultad de Ingeniera


Mdulo 5. Manejo dinmico de memoria (manejo de lista simplemente ligada)

q=p
p = p.retornaLiga()
q.asignaLiga(r)
end(while)
primero = q
fin(subprograma)

Este algoritmo pertenecer a la clase LSL ya que esta operacin, que se requiere con
objetos de la clase altaPrecision, tambin podr ser til en muchas otras situaciones.

Veamos cmo es nuestro algoritmo para el mtodo de suma:

1. altaPrecision sume(altaPrecision b)
2. nodoSimple p, q, acarreo
3. acarreo = new nodoSimple(0)
4. reversaLista()
5. b.reversaLista()
6. c = new altaPrecision()
7. p = primerNodo()
8. q = b.primerNodo()
9. while (no finDeRecorrido(p) and no b.finDeRecorrido(q)) do
10. c.evalue(p.retornaDato(), q.retornaDato(), acarreo)
11. p = p.retornaLiga()
12. q = q.retornaLiga()
13. end(while)
14. while (no finDeRecorrido(p))
15. c.evalue(p.retornaDato(), 0, acarreo)
16. p = p.retornaLiga()
17. end(while)
18. while (no finDeRecorrido(p))
19. c.evalue(0, q.retornaDato(), acarreo)
20. q = q.retornaLiga()
21. end(while)
22. if (acarreo.retornaDato() != 0) then
23. c.insertar(acarreo.retornaDato(), null)
24. end(if)
25. reversaLista()
26. b.reversaLista()
27. return c
28. fin(sume)

La instruccin 4 reversa los apuntadores del objeto que invoc el mtodo suma.

La instruccin 5 reversa los apuntadores del objeto enviado como parmetro.

El ciclo de instrucciones 9 a 13 es el ciclo principal del algoritmo: se recorren las dos listas
simultneamente sumando los contenidos de los datos de los nodos p, q y acarreo.

El ciclo de instrucciones 14 a 17 termina de recorrer la lista del objeto que invoc el mtodo
en caso de que haya terminado de recorrer primero la lista b.

El ciclo de instrucciones 18 a 21 termina de recorrer la lista del objeto enviado como pa-
rmetro en caso de que haya terminado de recorrer primero la lista que invoc el mtodo.

Algoritmia II 75|
En caso de que ambas listas se hubieran terminado de recorrer simultneamente no eje-
cuta ninguno de estos dos ciclos.

En la instruccin 22 se controla el hecho de que haya terminado de recorrer ambas listas


y que el acarreo sea diferente de 0.

En las instrucciones 25 y 26 se enderezan los apuntadores de las listas, los cuales haban
sido reversados en las instrucciones 4 y 5.

Adicionalmente, nuestro algoritmo de suma utiliza un mtodo denominado evalue, el cual


recibe como parmetros los datos a sumar, efecta la suma de ellos, separa los ltimos
cuatro dgitos e inserta un nodo al principio de la lista correspondiente al objeto que est
creando, es decir, el objeto c. El mtodo insertar utilizado en la instruccin 23 y en el m-
todo evalue es el definido para la clase LSL.

1. void evalue(entero d1, entero d2, nodoSimple acarreo)


2. entero s
3. s = d1 + d2 + acarreo.retornaDato()
4. acarreo.asignaDato(s/10000)
5. s = s % 10000
6. insertar(s, null)
7. fin(evalue)

Es conveniente resaltar que el tercer parmetro, acarreo, debe ser un parmetro por re-
ferencia. Esa es la razn por la cual lo hemos incluido dentro de un objeto de la clase
nodoSimple. Recuerde que el operador % retorna el residuo de una divisin entera.

Teniendo ya estos subprogramas elaborados podemos escribir un algoritmo que lea tres
nmeros de alta precisin y los sume:

altaPrecision a, b, c, d, e
a.leeNumero()
b.leeNumero()
c.leeNumero()
d = a.sume(b)
e = d.sume(c)
a.escribeNumero()
b.escribeNumero()
c.escribeNumero()
e.escribeNumero()

5.4 Escritura de un nmero de alta precisin


Presentamos ahora un algoritmo que es invocado por un objeto de la clase altaPreci-
sion e imprime el nmero representado en l. Recuerde que tomamos la decisin
de almacenar cuatro dgitos por nodo. Si el nmero que se est representando es
123444000003160028000765432543, la lista ligada que lo representa es (figura 5.5):

12 3444 0 316 28 7 6543 2543


primero ultimo
Figura 5.5

|76 Ude@-Facultad de Ingeniera


Mdulo 5. Manejo dinmico de memoria (manejo de lista simplemente ligada)

Aquellos nodos en los cuales se representan nmeros menores que 1000 hay que consi-
derarlos como casos especiales a la hora de imprimir. Si consideramos el nodo en el cual
est almacenado 316 y le decimos que escriba el dato de ese nodo el programa escribir
316, y nosotros necesitamos que escriba 0316; si consideramos el nodo en el cual est
almacenado 28 y le decimos que escriba el dato de ese nodo el programa escribir 28, y
nosotros necesitamos que escriba 0028; si consideramos el nodo en el cual est almace-
nado 7 y le decimos que escriba el dato de ese nodo el programa escribir 7, y nosotros
necesitamos que escriba 0007. La nica situacin en la cual se pueden omitir los ceros a
la izquierda es cuando se escriba el dato del primer nodo.

Un algoritmo que considera estas situaciones se presenta a continuacin.

1. void escribeAltaPrecision()
2. nodoSimple p
3. if (esVacia()) then return
4. p = primerNodo()
5. write(p.retornaDato()
6. p = p.retornaLiga()
7. while (no finDeRecorrido(p)) do
8. if (p.retornaDato() < 10) then
9. write(000)
10. else
11. if (p.retornaDato() < 100) then
12. write(00)
13. else
14. if (p.retornaDato() < 1000) then
15. write(0)
16. end(if)
17. end(if)
18. end(if)
19. write(p.retornaDato())
20. p = p.retornaLiga()
21. end(while)
22. fin(escribeAltaPrecision)

Ejercicios propuestos
1. Elabore un algoritmo que reste dos nmeros de alta precisin y deje el resultado en un
nuevo objeto.

2. Elabore un algoritmo que sume dos nmeros de alta precisin dejando el resultado en
el objeto que invoc el mtodo.

3. Elabore un algoritmo que multiplique dos nmeros de alta precisin dejando el resulta-
do en un nuevo objeto.

4. Elabore un algoritmo que divida dos nmeros de alta precisin dejando el resultado en
un nuevo objeto.

5. Elabore un algoritmo que calcule y retorne el factorial de un nmero de alta precisin.


El resultado debe ser otro objeto de la clase alta precisin.

Algoritmia II 77|

Potrebbero piacerti anche