Está en la página 1de 5

MÓDULO 9

LISTAS GENERALIZADAS

Contenido
9.1 Definición
9.2 Representación
9.3 Construcción de la lista ligada que representa una lista generalizada
9.4 Polinomios con más de una variable

Objetivos del módulo


Aprender el concepto de lista generalizada, su representación, manipulación y aplicación de ella.

Preguntas básicas
1. ¿Qué es una lista generalizada?
2. ¿Qué es un átomo?
3. ¿Cómo se representa una lista generalizada externamente a un computador?
4. ¿Cómo se representa una lista generalizada dentro de un computador?

Introducción
Hasta el momento se han tratado colecciones de datos en las cuales los elementos son átomos. Veremos
en este módulo una estructura más poderosa en la cual los elementos pueden ser átomos u otra colección.
Dicha estructura se denomina lista generalizada.

9.1 Definición. Una lista generalizada es un conjunto finito de n elementos (n >= 0) cada uno de los
cuales es un átomo u otra lista generalizada. La lista generalizada es una estructura recursiva por
definición ya que se define en términos de si mismo. Por ejemplo:

L = (a, (b, c), d, (e, (f, g)), h) {1}

Los átomos se presentan separados por comas, y cuando un elemento sea otra lista, ésta irá entre
paréntesis. Adoptamos como notación que las letras mayúsculas representan listas y que las letras
minúsculas representan átomos. Por ejemplo:

A = (a, b, c, d)

B = (a, A, f, A, g)

D = (A, B, x, A)

Si expandimos las listas B y D tendremos:

B = (a, (a, b, c, d), f, (a, b, c, d), g)

D = ((a, b, c, d), (a, (a, b, c, d), f, (a, b, c, d), g), x, (a, b, c, d))

9.2 Representación de Listas Generalizadas:


Las listas generalizadas las representaremos como listas ligadas. La configuración de cada nodo usa 3
campos:

Sw Dato Liga

0: En el campo de dato hay un átomo


Sw =
1: El campo dato es un apuntador hacia una sublista.

Cada elemento de la lista generalizada utiliza un nodo.

Representemos la lista L mostrada en {1} en la figura 9.1:


L  0 a  1  0 d  1  0 h 0

0 b  0 c 0
Sublista
0 e  1 0
Sublista

0 f  0 g 0
Sublista
Figura 9.1

9.3 Construcción de la lista ligada que representa una lista generalizada.


Para construir la lista ligada que representa una lista generalizada lo primero que debemos hacer es definir
la forma como entrarán los datos al programa de construcción. La entrada será una hilera de paréntesis
izquierdos, átomos, comas y paréntesis derechos, como en {1}.

Supondremos que la hilera que representa la lista generalizada está bien construida, es decir comienza
con un paréntesis izquierdo y termina con un paréntesis derecho.

Nuestro algoritmo recibe como parámetro de entrada una hilera s, en la cual está la hilera de paréntesis
izquierdos, átomos, comas y paréntesis derechos. Nuestro algoritmo, el cual pertenece a la clase lista
generalizada, y debe ser invocado por un objeto de dicha clase es:

1. void conslg(string s)
2. stack pila
3. x = new nodoLg(null)
4. L=x
5. ultimo = x
6. n = longitud(s)
7. for (i = 2; i < n; i++) do
8. casos de s[i]
9. átomo:
10. ultimo.asignaSw(0)
11. ultimo.asignaDato(s[i])
12. ”,”:
13. x = new nodoLg(null)
14. ultimo.asignaLiga(x)
15. ultimo = x
16. ’(‘:
17. pila.apilar(ultimo)
18. x = new nodoLg(null)
19. ultimo.asignaSw(1)
20. ultimo.asignaDato(x)
21. ultimo = x
22. ’)’:
23. ultimo = pila.desapilar()
24. fin(casos)
25. end(for)
26. Fin(conslg)

Con la instrucción 2 se define una pila vacía, la cual se utiliza en la construcción de las sublistas.

Instrucciones 3 a 5 inician la creación de la lista consiguiendo un registro, señalándolo como el primero


con la variable L, y a la vez, como la forma de construir la lista será añadiendo registros siempre al final de
la lista, identificamos este registro como el último, utilizando una variable llamada ultimo.
Instrucción 6 determina el número de caracteres de la hilera de entrada haciendo uso de la función
longitud, la cual ejecuta esta tarea.

Instrucciones 7 a 24 conforman el ciclo básico del algoritmo. En la hilera de entrada, los únicos símbolos
son: paréntesis izquierdos, átomos, comas y paréntesis derechos. Por consiguiente planteamos una
estructura caso, y dependiendo de cuál sea el símbolo en la posición i, efectuamos las operaciones
correspondientes. Si s(i) es un átomo basta con configurar el último registro con el sw en cero y llevar el
átomo s(i) al campo de dato (instrucciones 9 a 11). Si s(i) es una coma indica que a continuación vendrá
otro átomo u otra lista, por consiguiente conseguimos un nuevo registro, lo conectamos con el último y
decimos que este es el nuevo último (instrucciones 12 a 15). Si s(i) es un paréntesis izquierdo significa
que hay que construir una sublista, la cual se conectará con el campo de dato al registro que llevamos de
último; como esto es una interrupción a la construcción de una lista entonces guardamos la dirección del
último en la pila, conseguimos un nuevo registro, el cual será el nuevo último, y lo conectamos con el
último a través del campo de dato (instrucciones 16 a 21). Si s(i) es un paréntesis derecho significa que se
ha terminado de construir una sublista, por consiguiente, basta con retomar la construcción de la lista cuya
construcción se había interrumpido, asignándole a ultimo la dirección del registro que tenemos en el tope
de la pila (instrucción 23).

9.4 Polinomios con más de una variable.


Como ejemplo de aplicación de lista generalizadas trataremos el manejo de polinomios en más de una
variable.

Consideremos el siguiente polinomio:

2 3 2 2
x y z + 5x3yz2 + 7xy2z2 + 5x2yz + 4xz + 4x3y2 + 8y + 9 {2}

Una forma de representar dicho polinomio sería como lista ligada. Para ello definimos un registro con la
siguiente configuración:

Coef Exp X Exp Y Exp Z Liga

Con base en esta configuración del nodo la representación del polinomio {2} es

2 3 2 2  5 3 1 2  . . . 8 0 1 0  9 0 0 0 0

Esta representación es ineficiente, en cuanto a consumo de memoria, ya que en términos en los cuales el
exponente de alguna variable sea cero ese campo se considera desperdicio de memoria. Es decir, para el
término independiente del ejemplo tenemos tres campos de memoria cuyo valor es cero.

Además esta representación es muy rígida en el sentido de que sólo manejará polinomios de tres
variables. Si deseamos manejar polinomios en 5 variables, por ejemplo, debemos definir otra configuración
del nodo y elaborar el software correspondiente a esa configuración. En definitiva, nos llenaríamos de
múltiples representaciones y de un software específico para cada representación, dependiendo del número
de variables de los polinomios a trabajar. El objetivo es definir una representación única que nos permita
trabajar con cualquier polinomio, sin importar el número de variables que él tenga.

Si factorizamos el polinomio dado en {2} tendremos:

(2x3y2 + 5x3y + 7xy2)z2 + (5x2y + 4x)z + (4x3y2 + 8y + 9)

el cual, perfectamente podemos decir que es un polinomio en la variable z.


Si factorizamos los coeficientes de los términos en z obtenemos lo siguiente:

((2y2 + 5y)x3 + (7y2)x)z2 + ((5y)x2+ (4)x)z + ((4y2)x3 + (8y +9))


El cual es un polinomio en z cuyos coeficientes son polinomios en x, los cuales a su vez, tienen como
coeficientes polinomios en y. Como vemos, podemos perfectamente decir, que tenemos un polinomio en
una sola variable, cuyos coeficientes son polinomios en una sola variable, etc. Si deseamos representarlo
como lista generalizada debemos definir primero que todo la configuración del nodo. La configuración del
nodo es:
Sw Coef Exp Liga

Y puede manipularse en forma de lista generalizada

0: el campo COEF es un escalar

Sw =
1: el campo COEF es un apuntador a la lista que representa el polinomio que es coeficiente

Cada polinomio se representa como una lista simplemente ligada con nodo cabeza. Se usa un nodo por
cada término del polinomio. Representemos el polinomio anterior factorizado. El nodo cabeza tendrá Sw =
1, y su campo de coeficiente será un apuntador.

nodo cabeza.

1 5  1 2  1 1  1 0 0
..
1 8  1 3  1 0 0

1 7  0 4 2 0

1 7  0 8 1  0 9 0 0

1 8  1 2  0 4 1 0

7  0 5 1 0

1 8  1 3  1 1 0

1 7  0 7 2 0

1 7  0 2 2  0 5 1 0

5 Z 4,9 5
8 X 3,8 8

7 Y 5,6 7

Los campos de COEF, de los nodos cabeza son apuntadores hacia los registros donde se almacena el
nombre de la variable que representan, y su valor.

EJERCICIOS PROPUESTOS

1. Elabore un algoritmo que copie una lista generalizada en otra.

2. Elabore un algoritmo que determine si dos listas generalizadas son iguales.


3. Elabore un algoritmo que evalúe un polinomio representado como lista generalizada.

4. Escriba un algoritmo recursivo que construya una lista generalizada dada la representación de
paréntesis izquierdos, átomos, comas y paréntesis derechos.

5. Elabore un algoritmo que imprima una lista generalizada como una hilera de átomos, paréntesis
izquierdos y paréntesis derechos dada la representación como lista ligada.

6. Elabore un algoritmo que reverse una lista generalizada y todas sus sublistas.

También podría gustarte