• No se han encontrado resultados

Estructuras dinámicas lineales (ii)

N/A
N/A
Protected

Academic year: 2021

Share "Estructuras dinámicas lineales (ii)"

Copied!
5
0
0

Texto completo

(1)

Estructuras dinámicas lineales (ii)

Introducción

Continúa la exposición de los distintos algoritmos existentes para manipular listas simplemente enlazadas; sin el lección anterior se presentaban algoritmos iterativos, en ésta se verán en su versión recursiva.

Implementación de listas simplemente enlazadas en la notación algorítmica (ii)

Operaciones sobre listas (simplemente enlazadas) implementadas recursivamente

Recorrido de una lista simplemente enlazada (de forma recursiva)

acción recorrer (cabezaLista ∈ puntero a nodo) inicio

si cabezaLista ≠ NIL entonces escribir cabezaLista↑.numero

llamar recorrer (cabezaLista↑.siguiente) fin si

fin acción

En el algoritmo que se presenta el caso base podría decirse que es elíptico1 puesto que ninguna acción se debe realizar para recorrer una lista vacía; así, sólo aparece el caso recursivo que se limita a imprimir el contenido de la cabeza de la lista recibida y procede a recorrer el resto de la lista (una lista cuya cabeza es el elemento que sigue al actual).

A continuación se muestra de forma gráfica el recorrido recursivo de una lista con los números 1, 2 y 3:

llamar recorrer (lista)

2

3

lista 1

NIL

inicio

si cabezaLista ≠≠ NIL entonces escribir cabezaLista↑↑.numero

llamar recorrer (cabezaLista↑.siguiente) fin si

fin acción

La primera invocación de la acción imprime el contenido de la cabeza de la lista (1) y invoca de nuevo la acción para el resto de la lista.

3

lista 2

NIL

inicio

si cabezaLista ≠≠ NIL entonces escribir cabezaLista↑↑.numero

llamar recorrer (cabezaLista↑.siguiente) fin si

fin acción

La segunda invocación imprime el contenido de la cabeza de la lista, en este caso el resto de la lista anterior, con lo cual aparece por pantalla el número 2 y se invoca nuevamente la acción para el resto de la lista.

lista 3 NIL

inicio

si cabezaLista ≠≠ NIL entonces escribir cabezaLista↑↑.numero

llamar recorrer (cabezaLista↑.siguiente) fin si

fin acción

La tercera invocación imprime el contenido de la cabeza de la lista, en este caso el resto del resto de la lista anterior, mostrándose el número 3 e invocando la acción para el resto de la lista.

lista NIL

inicio

si cabezaLista ≠ NIL entonces escribir cabezaLista↑.numero

llamar recorrer (cabezaLista↑.siguiente)

fin si fin acción

Esta cuarta invocación recibe una lista vacía, por tanto, no hace nada y retorna a la tercera invocación que finaliza y retorna a la segunda que, a su vez, finaliza y retorna a la primera invocación que también finaliza y devuelve el control al programa principal.

(2)

Búsqueda de un elemento en una lista simplemente enlazada (de forma recursiva)

La operación de búsqueda se basa en la de recorrido; básicamente se trata de recorrer la lista hasta que se encuentre el elemento o se llegue al final, retornando un puntero al elemento encontrado (o NIL en caso contrario).

puntero a nodo función buscar (cabezaLista ∈ puntero a nodo, elemento ∈ entero) inicio

si cabezaLista ≠ NIL entonces

si cabezaLista↑.numero = elemento entonces buscar ß cabezaLista

si no

llamar buscar (cabezaLista↑.siguiente,elemento) fin si

si no

buscar ß NIL fin si

fin acción

Inserción de un elemento en una lista simplemente enlazada

Al igual que en la lección anterior, se procederá a implementar las operaciones de inserción en una cola y en una lista ordenada ascendentemente; la inserción en una pila no se puede implementar de forma recursiva puesto que es un problema que no consiste en una repetición de pasos.

Inserción en una cola (de forma recursiva)

Como ya se ha dicho, la inserción en una cola precisa buscar el último elemento de la lista e insertar el nuevo elemento detrás del mismo.

acción insertarCola (cabezaLista ∈ puntero a nodo, dato_nuevo ∈ entero) inicio

si cabezaLista ≠ NIL entonces

llamar insertarCola (cabezaLista↑.siguiente,dato_nuevo) si no

crear (cabezaLista)

cabezaLista↑.siguiente ß NIL cabezaLista↑.numero ß dato fin si

fin acción

A continuación se muestra de forma gráfica la inserción del número 3 en una lista que ya contiene los enteros 1 y 2: insertarCola (lista, 3) 2 lista 1 NIL inicio

si cabezaLista ≠≠ NIL entonces

llamar insertarCola (cabezaLista↑↑.siguiente,dato_nuevo)

si no

crear (cabezaLista)

cabezaLista↑.siguiente ß NIL cabezaLista↑.numero ß dato fin si

fin acción

En la primera invocación se comprueba que la cola no está vacía por lo que se procede a insertar, recursivamente, el elemento en el resto de la cola (2).

lista 2 NIL

inicio

si cabezaLista ≠≠ NIL entonces

llamar insertarCola (cabezaLista↑↑.siguiente,dato_nuevo)

si no

crear (cabezaLista)

cabezaLista↑.siguiente ß NIL cabezaLista↑.numero ß dato fin si

fin acción

En la segunda invocación se comprueba que la cola no está vacía por lo que se invoca recursivamente la acción para insertar el elemetno.

(3)

lista NIL

inicio

si cabezaLista ≠ NIL entonces

llamar insertarCola (cabezaLista↑.siguiente,dato_nuevo)

si no

crear (cabezaLista)

cabezaLista↑.siguiente ß NIL cabezaLista↑.numero ß dato fin si

fin acción

En la tercera invocación la cola está vacía, por tanto, es posible crear un nuevo elemento.

lista

inicio

si cabezaLista ≠ NIL entonces

llamar insertarCola (cabezaLista↑.siguiente,dato_nuevo) si no

crear (cabezaLista)

cabezaLista↑.siguiente ß NIL cabezaLista↑.numero ß dato fin si

fin acción

El nuevo elemento es creado.

lista NIL

inicio

si cabezaLista ≠ NIL entonces

llamar insertarCola (cabezaLista↑.siguiente,dato_nuevo) si no

crear (cabezaLista)

cabezaLista↑↑.siguiente ßß NIL

cabezaLista↑.numero ß dato fin si

fin acción

El nuevo elemento es el primero y el último de su cola.

lista 3 NIL

inicio

si cabezaLista ≠ NIL entonces

llamar insertarCola (cabezaLista↑.siguiente,dato_nuevo) si no

crear (cabezaLista)

cabezaLista↑.siguiente ß NIL

cabezaLista↑↑.numero ßß dato fin si

fin acción

Se asigna un valor al nuevo elemento y se retorna desde la tercera invocación a la segunda.

3

lista 2

NIL

inicio

si cabezaLista ≠ NIL entonces

llamar insertarCola (cabezaLista↑.siguiente,dato_nuevo) si no

crear (cabezaLista)

cabezaLista↑.siguiente ß NIL cabezaLista↑.numero ß dato

fin si fin acción

La segunda invocación ya ha insertado, recursivamente, el nuevo elemento así que puede retornar a la primera.

2

lista 1

inicio

si cabezaLista ≠ NIL entonces

llamar insertarCola (cabezaLista↑.siguiente,dato_nuevo) si no

crear (cabezaLista)

cabezaLista↑.siguiente ß NIL cabezaLista↑.numero ß dato

(4)

acción insertarOrdenado (cabezaLista ∈ puntero a nodo, dato ∈ entero) variables

nuevo ∈ puntero a nodo inicio

si cabezaLista ≠ NIL entonces

si cabezaLista↑.numero ≥ dato entonces crear (nuevo)

nuevo↑.siguiente ß cabezaLista↑.siguiente cabezaLista↑.siguiente ß nuevo

nuevo↑.numero ß cabezaLista↑.numero cabezaLista↑.numero ß dato

si no

llamar insertarOrdenado (cabezaLista↑.siguiente,dato) fin si

si no

crear (cabezaLista)

cabezaLista↑.siguiente ß NIL cabezaLista↑.numero ß dato fin si

fin acción

Eliminar un elemento de una lista simplemente enlazada (de forma recursiva)

El algoritmo básico de eliminación simplemente debe recorrer la lista hasta encontrar el dato a eliminar, enlazar la lista de forma adecuada y destruir el nodo sobrante.

acción eliminarElemento (cabezaLista ∈ puntero a nodo, dato ∈ entero) variables

cursor ∈ puntero a nodo inicio

si cabezaLista ≠ NIL entonces

si cabezaLista↑.numero = dato entonces si cabezaLista↑.siguiente ≠ NIL entonces cursor ß cabezaLista↑.siguiente cabezaLista↑.numero ß cursor↑.numero cabezaLista↑.siguiente ß cursor↑.siguiente destruir (cursor)

si no

destruir (cabezaLista) fin si

si no

si cabezaLista↑.siguiente ≠ NIL entonces

si cabezaLista↑.siguiente↑.numero = dato entonces cursor ß cabezaLista↑.siguiente

cabezaLista↑.siguiente ß cursor↑.siguiente destruir (cursor)

si no

llamar eliminarElemento (cabezaLista↑.siguiente,dato) fin si

fin si fin si fin si fin acción

Vaciado de una lista simplemente enlazada (de forma recursiva)

acción vaciarLista (cabezaLista ∈ puntero a nodo) inicio

si cabezaLista↑.siguiente ≠ NIL entonces llamar vaciarLista (cabezaLista↑.siguiente) fin si

destruir(cabezaLista) fin acción

Para vaciar una lista simplemente enlazada de forma recursiva basta con vaciar el resto de la lista, si es que existe, y después eliminar el nodo que se encuentra en la cabeza.

A continuación se muestra de forma gráfica el vaciado recursivo de la lista que contiene los números 1, 2 y 3.

(5)

2

3

lista 1

NIL

inicio

si cabezaLista↑↑.siguiente ≠≠ NIL entonces llamar vaciarLista (cabezaLista↑↑.siguiente)

fin si

destruir(cabezaLista) fin acción

En la primera invocación se debe vaciar el resto de la lista (2 y 3).

3

lista 2

NIL

inicio

si cabezaLista↑↑.siguiente ≠≠ NIL entonces llamar vaciarLista (cabezaLista↑↑.siguiente)

fin si

destruir(cabezaLista) fin acción

En la segunda invocación se debe vaciar el resto de la lista (3).

lista 3 NIL

inicio

si cabezaLista↑.siguiente ≠ NIL entonces llamar vaciarLista (cabezaLista↑.siguiente) fin si

destruir(cabezaLista)

fin acción

En la tercera invocación no hay resto de lista con lo cual se destruye la cabeza (3).

lista

inicio

si cabezaLista↑.siguiente ≠ NIL entonces llamar vaciarLista (cabezaLista↑.siguiente) fin si

destruir(cabezaLista)

fin acción

Una vez destruida la cabeza de la lista en la tercera invocación se retorna a la segunda.

lista 2

inicio

si cabezaLista↑.siguiente ≠ NIL entonces llamar vaciarLista (cabezaLista↑.siguiente) fin si

destruir(cabezaLista)

fin acción

En la segunda invocación ya se ha vaciado el resto de la lista, por lo que se puede destruir la cabeza (2).

lista

inicio

si cabezaLista↑.siguiente ≠ NIL entonces llamar vaciarLista (cabezaLista↑.siguiente) fin si

destruir(cabezaLista)

fin acción

Destruida la cabeza de la lista de la segunda invocación se puede retornar a la primera.

lista 1

inicio

si cabezaLista↑.siguiente ≠ NIL entonces llamar vaciarLista (cabezaLista↑.siguiente) fin si

destruir(cabezaLista)

fin acción

Al haberse vaciado el resto de la lista en la primera invocación se elimina la cabeza.

inicio

si cabezaLista↑.siguiente ≠ NIL entonces llamar vaciarLista (cabezaLista↑.siguiente) fin si

Referencias

Documento similar

Cedulario se inicia a mediados del siglo XVIL, por sus propias cédulas puede advertirse que no estaba totalmente conquistada la Nueva Gali- cia, ya que a fines del siglo xvn y en

El nuevo Decreto reforzaba el poder militar al asumir el Comandante General del Reino Tserclaes de Tilly todos los poderes –militar, político, económico y gubernativo–; ampliaba

1º) una motivación social minusvaloradora, despectiva o, incluso, estigmatizadora: las personas contra las que se discrimina, caracterizadas por lo general mediante su pertenencia a

In medicinal products containing more than one manufactured item (e.g., contraceptive having different strengths and fixed dose combination as part of the same medicinal

Products Management Services (PMS) - Implementation of International Organization for Standardization (ISO) standards for the identification of medicinal products (IDMP) in

Products Management Services (PMS) - Implementation of International Organization for Standardization (ISO) standards for the identification of medicinal products (IDMP) in

This section provides guidance with examples on encoding medicinal product packaging information, together with the relationship between Pack Size, Package Item (container)

Package Item (Container) Type : Vial (100000073563) Quantity Operator: equal to (100000000049) Package Item (Container) Quantity : 1 Material : Glass type I (200000003204)