TLista

download TLista

of 9

description

Estructura de Datos

Transcript of TLista

  • TLista.pas

    (*--------------------------------------------------------------*)(* Mdulo: TLista *)(* Fichero: ()Programa (X)Espec.TAD (X) Impl. TAD (X) Otros *)(* Autor: *)(* Fecha: *)(* Descripcin: TAD TipoLista. Implementacin con lista *)(* enlazada simple. *)(*--------------------------------------------------------------*)

    unit TLista;{------------------------------------------------------------------------}{ ESPECIFICACIN TAD TipoLista

    PARAMETROS GENRICOSTIPO: TipoElementoOPERACIONES: SonElementosIguales: TipoElemento x TipoElemento -> Boolean

    EsElementoMayor: TipoElemento x TipoElemento -> BooleanFIN PARAMETROS

    OPERACIONES:

    - CONSTRUCTORAS GENERADORAS: CrearVacia : -> TipoLista InsertarPrincipio: TipoElemento x TipoLista -> TipoLista

    - OBSERVADORAS SELECTORAS: [parcial] Primero : TipoLista -> TipoElemento [parcial] Resto : TipoLista -> TipoLista [parcial] Enesimo: Integer x TipoLista -> TipoElemento [parcial] Ultimo: TipoLista -> TipoElemento

    - OBSERVADORAS NO SELECTORAS: EsVacia : TipoLista -> booleano Longitud : TipoLista -> Integer Pertenece : TipoElemento x TipoLista -> Booleano Igual: TipoLista x TipoLista -> Booleano

    - CONSTRUCTORAS NO GENERADORAS: Concatenar : TipoLista x TipoLista -> TipoLista Copiar : TipoLista -> TipoLista BorrarElemento : TipoElemento x TipoLista -> TipoLista InsertarFinal: TipoElemento x TipoLista -> TipoLista

    VARIABLES:

    lista, lista2: TipoLista; elemento: TipoElemento; posicion: TipoPosicion;

    ECUACIONES:

    CrearVacia() = lista Efecto: devuelve una lista con cero elementos

    InsertarPrincipio(elemento, lista) = lista Efecto: Insterta por el principio un elemento en la lista.

    Primero(lista) = elemento Requerimiento: la lista no puede estar vaca Efecto: devuelve el primer elemento de la lista

    Resto(lista) = lista2 Requerimiento: la lista no puede estar vaca Efecto: devuelve lista2, que es el resto de la lista que

    Page 1

  • TLista.pas

    hay despus del primer elemento, sin modificar lista.

    Ultimo(lista) = elemento Requerimiento: la lista no puede estar vaca Efecto: devuelve el ltimo elemento de la lista.

    EsVacia(lista) = BOOLEANO Efecto: devuelve CIERTO si la lista no contiene ningn elemento y FALSO si contiene elementos.

    Longitud(lista) = ENTERO Efecto: si la lista est vaca devuelve cero y si no, devuelve el nmero de elementos de la lista.

    Pertenece(elemento, lista) = BOOLEANO Requisito: TipoElemento debe poseer la operacin comparacin de dos elementos. Efecto: si elemento es igual a algn elemento de la lista devuelve CIERTO, y si no, devuelve FALSO.

    Copiar(lista) = lista2 Efecto: devuelve lista2, que es igual a lista. Equivale al operador asignacin, que asigna lista a lista2.

    Concatenar(lista, lista2) = listaEfecto: si lista es vaca devuelve la lista con los elementos de lista2, si lista2 es vaca devuelve lista sin modificar, y si ninguna es vaca devuelve lista modificada, con los elementos de lista seguidos por los de lista2 aadidos al final.

    BorrarElemento (elemento, lista) = lista Efecto: si lista es vaca o si no se encuentra en ella el elemento, devuelve la lista sin modificar. Si no, si elemento se encuentra en la lista devuelve lista sin ese elemento.

    InsertarFinal (elemento, lista) = lista Efecto: devuelve la lista modificada, con el elemento aadido al final.

    Enesimo(posicion, lista) = elemento Efecto: devuelve el elemento situado en la posicin de la lista que indica posicin.

    Igual(lista, lista2) = BOOLEANO Efecto: devuelve CIERTO si las listas lista y lista2 son iguales, y en caso contrario devuelve FALSO.

    FIN ESPECIFICACIN TAD TipoLista}{-------------------------------------------------------------------------------------}INTERFACE {Definicin de la parte pblica}{-------------------------------------------------------------------------------------}

    USES TElemento;

    TYPE

    TipoLista = ^TipoNodo; TipoNodo = RECORD dato : TipoElemento; siguiente : TipoLista END; (* registro *)

    PROCEDURE CrearVacia (VAR lista: TipoLista);(* POST: "Crea una lista sin elementos: []" *)

    PROCEDURE InsertarPrincipio (elemento: TipoElemento; VAR lista: TipoLista);(* POST: "Construye una lista, dados un elemento y una lista *)

    Page 2

  • TLista.pas

    FUNCTION Primero (lista: TipoLista): TipoElemento;(* PRE: NOT EsVacia(lista) *)(* POST: resultado = "Primer elemento de una lista *)

    FUNCTION Resto (lista: TipoLista):TipoLista;(* PRE: NOT EsVacia(lista) *)(* POST: "Devuelve la lista que sigue al primer elemento, sin modificar la lista*)

    FUNCTION EsVacia (lista: TipoLista): BOOLEAN;(* POST: resultado = (lista = []) *)

    FUNCTION Longitud (lista: TipoLista): INTEGER;(* POST: resultado = "numero de elementos de la lista" *)

    FUNCTION Ultimo (lista: TipoLista): TipoElemento;(* PRE: NOT EsVacia(lista) *)(* POST: resultado = "elemento que ocupa la posicion final en la lista" *)

    FUNCTION Pertenece (elemento: TipoElemento; lista: TipoLista): BOOLEAN;(* POST: resultado = (elemento EN lista) *)

    PROCEDURE Copiar (lista: TipoLista; VAR lista2: TipoLista);(* POST: "devuelve lista2, que es igual a lista. Equivale al operador asignacin, que asigna lista a lista2." *)

    PROCEDURE Concatenar (VAR lista: TipoLista; VAR lista2: Tipolista);(* POST: "lista3 toma el resultado de aadir al final de lista la estructura de lista2*)

    PROCEDURE BorrarElemento (elemento: TipoElemento; VAR lista: TipoLista);(* POST: Elimina, si existe, la primera aparicion de elemento en lista *)

    PROCEDURE InsertarFinal (elemento: TipoElemento; VAR lista: TipoLista);(* POST: Anyade el elemento haciendo que ocupe la ultima posicion de la lista *)

    PROCEDURE Enesimo (posicion: Integer; lista: TipoLista; VAR elemento: TipoElemento);(* PRE: 1

  • TLista.pas

    END;{--------------------------------------------------}FUNCTION Primero (lista: TipoLista): TipoElemento;(* PRE: NOT EsVacia(lista) *)(* POST: resultado = "Primer elemento de una lista *)(* COMPLEJIDAD: O(1) *)BEGIN

    IF NOT EsVacia (lista) THEN Primero := lista^.dato ELSE WRITELN('Error en Function Primero: la lista es vaca.');END;{--------------------------------------------------------}FUNCTION Resto (lista: TipoLista): TipoLista;(* PRE: NOT EsVacia(lista) *)(* POST: "Devuelve la lista que sigue al primer elemento, sin modificar la lista*)(* COMPLEJIDAD: O(1) *)BEGIN

    IF NOT EsVacia (lista) THEN Resto := lista^.siguiente ELSE WRITELN('Error en Function Resto: la lista es vaca.')END;{--------------------------------------------}FUNCTION EsVacia (lista: TipoLista): BOOLEAN;(* POST: resultado = (lista = []) *)(* COMPLEJIDAD: O(1) *)BEGIN

    EsVacia := (lista = NIL)END;{---------------------------------------------}FUNCTION Longitud (lista: TipoLista): INTEGER;(* POST: resultado = "numero de elementos de la lista" *)(* COMPLEJIDAD: O(N), siendo N el numero de elementos de la lista *)VAR

    long : integer; pAux : TipoLista;BEGIN

    pAux := lista; long := 0; WHILE pAux NIL DO BEGIN long := long + 1; pAux := pAux^.siguiente END; Longitud := longEND;

    (* NOTA: Funcin Longitud recursiva:

    FUNCTION Longitud (lista: TipoLista): INTEGER;

    BEGINIF EsVacia(lista) THEN

    Longitud := 0ELSE

    BEGINLongitud := 1 + Longitud(resto(lista))

    END;END;*){------------------------------------------------}FUNCTION Ultimo (lista: TipoLista): TipoElemento;

    Page 4

  • TLista.pas

    (* PRE: NOT EsVacia(lista) *)(* POST: resultado = "elemento que ocupa la posicion final en la lista" *)(* COMPLEJIDAD: O(N) *)VAR

    pAux : TipoLista;BEGIN

    IF NOT EsVacia (lista) THEN {la lista tiene algn elemento} BEGIN pAux := lista; WHILE pAux^.siguiente NIL DO pAux := pAux^.siguiente; Ultimo := pAux^.dato END ELSE WRITELN('Error en Function Ultimo: la lista es vaca' )END;{------------------------------------------------------------------------}FUNCTION Pertenece (elemento: TipoElemento; lista: TipoLista): BOOLEAN;(* POST: resultado = (elemento EN lista) *)(* COMPLEJIDAD: O(Longitud(lista)) *)VAR

    pAux : TipoLista; esta : BOOLEAN;BEGIN

    pAux := lista; esta := FALSE; WHILE (pAux NIL) AND NOT esta DO BEGIN IF SonElementosIguales(pAux^.dato, elemento) THEN (* NOTA: implementar esta operacin en el TAD parmetro TipoElemento, en vez usar directamente "pAux^.dato = elemento" proporciona genericidad al TAD TipoLista, que servir tanto si TipoElemento es simple como si es compuesto *) esta := TRUE ELSE pAux :=pAux^.siguiente END; Pertenece := estaEND;{-----------------------------------------------------------------------------------}PROCEDURE Copiar (lista: TipoLista; VAR lista2: TipoLista);(* POST: "Copia la lista en la estructura lista2" *)(* COMPLEJIDAD: O(Longitud(lista)) *)VAR

    pAux, pUltimo2, nuevo: TipoLista;BEGIN

    IF EsVacia (lista) THEN {lista es vaca} CrearVacia (lista2) ELSE BEGIN {lista tiene elementos} pAux := lista; new (nuevo); {caso especial: copia del primer elemento, lista2 lo apuntar} nuevo^.dato := pAux^.dato; nuevo^.siguiente := NIL; lista2 := nuevo; pUltimo2 := nuevo; (*pUltimo2 indica la posicin en lista2 del ltimo elemento copiado, necesario para aadirle el prximo elemento a copiar*) pAux := pAux^.siguiente; WHILE pAux NIL DO BEGIN {copia del resto de elementos} new (nuevo); nuevo^.dato := pAux^.dato;

    Page 5

  • TLista.pas

    nuevo^.siguiente := NIL; pUltimo2^.siguiente := nuevo; pUltimo2 := nuevo; pAux := pAux^.siguiente END ENDEND;{-----------------------------------------------------------------------------------}

    PROCEDURE Concatenar (VAR lista: TipoLista; VAR lista2: Tipolista);(* POST: "se aade al final de lista la estructura lista2 y lista2 queda vaca*)(* COMPLEJIDAD: O(Longitud(lista)) *)VAR

    pAux: TipoLista; (* punteros auxiliares para recorrido de 'lista' *)

    BEGIN

    IF NOT EsVacia (lista2) THEN {lista2 no es vaca} IF EsVacia (lista) THEN lista := lista2 {lista es vaca pero lista2 no} ELSE BEGIN {lista y lista2 no son vacas} pAux := lista; {busco el puntero al ltimo elemento de lista para aadir ah lista2} WHILE pAux^.siguiente NIL DO pAux := pAux^.siguiente; pAux^.siguiente := lista2 {se aade lista2 al final de lista1}

    END; lista2:= NIL;

    END;{-----------------------------------------------------------------------------------}{NOTA: Vase la diferencia entre Concatenar y Concatenar2.}

    PROCEDURE Concatenar2 (lista, lista2: Tipolista; VAR lista3: TipoLista);(* POST: "lista3 toma como resultado una copia de lista seguida de una copia de lista2 COMPLEJIDAD: O(Longitud(lista)+Longitud(lista2)) *)VAR

    pAct4, lista4 : TipoLista; (* punteros auxiliares para recorrido de 'lista' *)

    BEGIN

    IF EsVacia (lista) THEN {lista es vaca} IF EsVacia (lista2) THEN CrearVacia (lista3) {lista y lista2 son vacas -> lista3 ser vaca} ELSE Copiar (lista2, lista3) {lista es vaca pero lista2 no -> lista3 ser lista2} ELSE {lista no es vaca} IF EsVacia (lista2) THEN Copiar (lista, lista3) {lista no es vaca pero lista2 s -> lista3 ser lista}

    ELSE

    BEGIN {lista y lista2 no son vacas} Copiar (lista2, lista3); {copio lista2 en lista3} Copiar (lista, lista4); {copio lista en lista4} pAct4 := lista4; WHILE pAct4^.siguiente NIL DO {busco el puntero al ltimo elemento de lista4 para aadir ah lista3} BEGIN pAct4 := pAct4^.siguiente END; pAct4^.siguiente := lista3; lista3 := lista4

    END

    END;

    Page 6

  • TLista.pas

    {-----------------------------------------------------------------------------------}PROCEDURE BorrarElemento (elemento: TipoElemento; VAR lista: TipoLista);(* POST: Elimina, si existe, la primera aparicion de elemento en lista. Si la lista est vacael resultado es la lista vaca *)(* COMPLEJIDAD: O(Longitud(lista)) *)VAR

    pAct, pAnt: TipoLista; encontrado: boolean;

    BEGIN

    encontrado := FALSE;

    IF NOT EsVacia (lista) THEN BEGIN pAct := lista; pAnt := NIL;

    WHILE (pAct NIL) AND (NOT encontrado) DO (*bsqueda de la 1 aparicin del elemento*) BEGIN IF SonElementosIguales(pAct^.dato, elemento) THEN (* NOTA: implementar esta operacin en el TAD parmetro TipoElemento, en vez usar directamente "pAct^.dato = elemento" proporciona genericidad al TAD TipoLista, que servir tanto si TipoElemento es simple como si es compuesto *) encontrado := TRUE ELSE BEGIN pAnt := pAct; pAct := pAct^.siguiente END END; (* end while*)

    IF encontrado THEN (* elemento encontrado -> eliminacin*) IF (pAnt = NIL) THEN (*es el primer elemento de la lista: hay que modificar lista *)

    IF (pAct^.siguiente = NIL) THEN (* la lista tiene slo un elemento *)BEGIN

    dispose(lista);lista := NIL

    END

    ELSE (* la lista tiene ms de un elemento *)BEGIN

    lista := pAct^.siguiente;dispose(pAct);

    END

    ELSE (* no es el primer elemento *) BEGIN (* se hace igual tanto si es el ltimo como si es uno central *)

    pAnt^.siguiente := pAct^.siguiente; Dispose (pAct) END END {end IF NOT EsVacia(lista)}END; {end procedure}{-----------------------------------------------------------------------------------}PROCEDURE InsertarFinal (elemento: TipoElemento; VAR lista: TipoLista);(* COMPLEJIDAD: O(Longitud(lista)= O(N)) *)VAR

    pAct: TipoLista; nuevo: TipoLista; (* nuevo nodo a aadir al final de la lista*)BEGIN

    Page 7

  • TLista.pas

    IF EsVacia (lista) THEN InsertarPrincipio (elemento, lista) ELSE BEGIN pAct := lista; WHILE pAct^.siguiente NIL DO pAct := pAct^.siguiente;

    New (nuevo); nuevo^.dato := elemento; nuevo^.siguiente := NIL; pAct^.siguiente := nuevo ENDEND;{-----------------------------------------------------------------------------------}PROCEDURE Enesimo (posicion: Integer; lista: TipoLista; VAR elemento: TipoElemento);(* PRE: 1

  • TLista.pas

    end.

    Page 9