Ingeniero Técnico en Informática de Sistemas


Estructura de Datos


TEMA 1: Introducción a las estructuras y tipos de datos

  • .- Introducción

  • .- Abstracción de datos

  • .- Concepto de Tipo Abstracto de Datos (TAD)

  • 1.1.- Introducción

    La informática es la ciencia para el tratamiento automático de la información. Para llevar a cabo este proceso automático hay que tener en cuenta dos puntos:

  • cómo se va a representar la información en el ordenador.

  • cómo se va a manipular esta información según la representación escogida.

  • La única información que entiende un ordenador es una secuencia de 1's y 0's. Por tanto las estructuras de datos que utilicemos serán trasladadas a ristras de ceros y unos para implementarlas en el ordenador

    1001001101 estructura de datos

    ¿entero?

    ¿real?

    ¿caracter?

    y estas estructuras llevarán implícitas unas operaciones características de cada una de ellas con las que podrán agruparse o modificarse.

    TIPOS de DATOS

    Un tipo de Datos consta de dos partes:

  • una estructura con que implementarse en un ordenador.

  • unas operaciones implícitas a la estructura con la que manipularla.

  • Encontramos tres tipos de estructuras: Básicas, Predefinidas, y Definidas por el usuario.

    • Básicas (Entero, Real, Caracter, Booleano).

    • Predefinidas (Array, Registros, Conjuntos).

    • Definidos por el Usuario (Pila, Cola, Lista, Árbol, Grafos).

    Por tanto un tipo de datos consiste en una estructura dotada de operaciones.

    1.2.- Abstracción de datos

    La acción de abstracción de datos consiste en trasladar la información del mundo real de forma ajustada a datos manejables por el ordenador. Para ello debe seleccionarse solamente la información significativa para la abstracción y desechar el resto.

    El proceso de abstracción se compone de 4 etapas:

    • 1ªetapa: Abstracción. En esta etapa se analizan las propiedades del tipo real y se seleccionan datos significativos para su posterior implementación.

    • 2ªetapa: Representación. Se busca la mejor forma de implementar estas propiedades en el ordenador.

    • 3ªetapa: Manipulación. Consiste en establecer reglas para un correcto manejo del tipo de datos en el ordenador.

    • 4ªetapa: Axiomatización. Representación matemática formal.

    Ejemplos:

    Los números naturales

    Abstracción: Cardinalidad de un conjunto para representarlo.

    Representación => Manipulación

    I I I I I I I I I I + I I = I I I I I I

    Numeración romana

    VII, X, C LVI + XLIV = C

    Sistema de numeración árabe

    1327 = 1*103 + 3*102 + 2*10 + 7

    56 + 44 = 100

    Una buena estructuración de los datos se traduce en una estructura más simple de los algoritmos.

    Tipo de dato = Estructura + Operaciones de Manipulación

    En resumen, proceso de abstracción consiste en:

    • Abstracción: Definir y extraer las propiedades características de la información del mundo real.

    • Representación + Manipulación: Seleccionar el tipo idóneo para representar la información a manipular. Esta selección también debe realizarse a favor de simplificar la implementación de sus operaciones.

    • Axiomatización: Teoremas que permitan probar que el proceso global ha sido correcto.

    1.3.- Tipo Abstracto de Datos (TAD)

    Tenemos dos clases de TAD's:

    • Tipos predefinidos: definidos por el lenguaje.

    • Tipos definidos por el usuario: los define el programador.

    Unit PILAS

    • definir estructura de datos para implementar una PILA.

    • definir los algoritmos para la implementación de las operaciones de la PILA.

    De esta forma de consigue un encapsulamiento.

    Cuando definimos una UNIDAD en Pascal (MODULO en Modula-2) como la descrita, concentramos en ella la estructura de un tipo abstracto de datos y las operaciones de manipulación de esta en forma de procedimientos y funciones. Con ello tendremos localizado todo lo referente a una estructura de datos en la UNIT. A esto se le llama encapsulamiento y tiene la ventaja de que en caso de querer localizar una operación en concreto nos será más eficiente si todo está ordenado.

    TAD: Se puede pensar en un tipo abstracto de datos como en un modelo matemático con una serie de operaciones definidas sobre ese modelo. Los TAD son generalizaciones de un tipo de datos primitivo (enteros, reales, ...). Un TAD encapsula cierto tipo de datos en el sentido de que es posible localizar la definición del tipo y todas sus operaciones en una misma porción del programa. Esto facilita posibles modificaciones posteriores ya que el resto del código no dependerá de la implementación del TAD. Con esto se consigue tratar el TAD como un tipo de datos primitivo. Hay que tener en cuenta que ciertas operaciones pueden implicar más de un TAD y deberá hacerse referencia a estas operaciones en los dos TAD's.

    TIPO de DATOS: El tipo de datos de una variable es aquellos valores que ésta puede tomar. Los tipos de datos básicos son en Pascal, entero, real, booleano y caracter. Las reglas para construir tipos compuestos (predefinidas y definidas por el usuario) a partir de estos básicos varían en función del lenguaje de implementación. Para implementar un algoritmo en un lenguaje de programación determinado, debe de hallarse un mecanismo de representar los TAD en función de los tipos de datos y los operadores manejados por ese lenguaje.

    ESTRUCTURA de DATOS: Para representar el modelo matemático básico de un TAD se emplean estructuras de datos. Estas son conjuntos de variables, pueden ser de distintos tipos, conectadas entre sí de diversas formas.

    Ejemplo de TAD

    • Supongamos el TAD números naturales,

    • operaciones constructoras:

    operación cero: ! natural

    operación sucesor: natural ! natural

    operación suma: natural x natural ! natural [producto cartesiano]

    • propiedades: " m, n " N

    suma (0, n) = n

    suma (succ (n), m) = succ (suma (n, m))

    3 + 2 =

    suma (succ (succ (succ (0))), succ (succ (0))) =

    = succ (suma (succ (succ (0)), succ (succ (0)))) =

    = succ (succ (suma (succ (0),succ (succ (0))))) =

    = succ (succ (succ (suma (0, succ (succ (0)))))) =

    = succ (succ (succ (succ (succ (0))))) = 5

    • Tipo Abstracto de Datos PILA,

    Operaciones Apilar, Desapilar, PilaVacía, CrearPila, Tope.

    TEMA 2: Tipos y Estructuras Básicas

  • .- Introducción.

  • .- Tipos escalares

  • 1.- Tipos normalizados

  • 2.- Tipos definidos por el usuario

  • - Tipos estructurados

  • 1.- Tipo VECTOR

  • 2.- Tipo CONJUNTO

  • 3.- Tipo REGISTRO

  • 2.1.- Introducción

    Distinguimos los tipos de datos en escalares, estructurados, y punteros. De estos 3 sólo profundizaremos en los dos primeros, los punteros los dejamos para más adelante.

    Normalizados (Entero, Real, Caracter, Booleano)

    ESCALARES Subrango

    (=, <, >, ", ", ") Definidos por el usuario

    Enumerados

    Array (Tabla)

    Conjunto

    ESTRUCTURADOS

    Registro

    Fichero

    CARDINAL: El cardinal de un tipo (o tipo de datos) es el número de valores posibles en ese tipo.

    2.2.- Tipos Escalares

    Un tipo de datos es ESCALAR si existe una relación de orden entre todos los elementos de ese tipo. En los tipos escalares se pueden utilizar los operadores relacionales (=, <, >, ", ", "). Todos los tipos de datos escalares, excepto el tipo Real, son ordinales. Esto es, que a cada elemento de estos tipos se le puede asociar un precedente, un sucesor, y un ordinal (la posición que ocupa entre los valores de su tipo).

    2.2.1.- Tipos normalizados

    • Tipo entero

  • Conjunto de valores asociados pertenecientes al subconjunto de los enteros infinitos (ya que en un ordenador su representación no es infinita). El rango de representación variará dependiendo del ordenador y/o el lenguaje de programación.

  • {(- maxentero + 1), maxentero}

  • El tipo entero es escalar y ordinal.

  • Los operadores utilizados con el tipo entero se clasifican en 3 grupos:

    • Aritméticos: +, -, *, DIV, MOD

    • Relacionales: <, ", =, ", ", >

    • Ordinales: pred, succ, ord

  • Implementación en el ordenador. Normalmente con n bits de los cuales uno es para el signo. Max_entero = 2n-1 -1. En TurboPascal se usan 5 representaciones: byte, shortint, integer, longint y word.

    • Tipo real

  • Conjunto de valores asociados pertenecientes al subconjunto de R. Al igual que los enteros su rango se ve limitado por el lenguaje y el ordenador usados, además en los números reales también se ve afectado por la precisión en la representación. La precisión hace referencia al menor nº real distinguible de cero.

  • {[- maxreal .. - minreal] , [minreal .. maxreal]}

  • Es un tipo escalar y el único de su clase no ordinal (el resto de escalares lo son).

  • En el tipo reales sólo encontramos operadores del tipo aritméticos y relacionales:

    • Aritméticos: +, -, *, /, sqrt, sqr, ln, sen, cos, tg, ...

    • Relacionales: <, ", =, ", ", >

  • Implementación. Los reales suelen representarse en forma mantisa/exponente. En TurboPascal hay 5 representaciones posibles: Real, simple, double, extended y comp.

  • Relaciones entre entero y real

    • Conversión de entero a real: Operar un entero con un real da como resultado un real. El conjunto de los enteros es subconjunto del de los reales.

    • Conversión de real a entero:

    • Truncamientos (trunc): Se eliminan las cifras a la derecha de la coma.

    • Redondeo (round): Se eliminan las cifras decimales sumándole una unidad al número restante si la primera cifra decimal en mayor que 5 y restándole una unidad si la cifra decimal es menor que 5.

    • round (a) = trunc (a + 0.5)

    • Tipo caracter

  • Conjunto de valores asociados formado por un conjunto de caracteres imprimibles que comprende:

    • Caracteres del alfabeto latino.

    • Dígitos arábigos.

    • Caracteres especiales y de control.

    Para formalizar este conjunto de valores se imponen dos condiciones:

    • Es un subconjunto de un alfabeto ordenado y coherente. Puede incluir letras, dígitos y otros caracteres, por eso es un subconjunto de un alfabeto.

    • Existe un caracter (b) que no es imprimible.

    Normalmente se admite la tabla ASCII como estándar.

  • Gracias al ASCII es considerado un tipo escalar y ordinal.

  • Operadores. Carece de operadores aritméticos:

    • Relacionales: <, ", =, ", ", >

    • Ordinales: pred, succ, ord.

  • Implementación. Un caracter suele representarse por la representación binaria del caracter en la tabla ASCII (la posición que ocupa en esta tabla).

  • Relaciones entre caracter y entero

    • Conversión de caracter a entero (ord): La función ordinal de un caracter devuelve el valor entero de la posición que ocupa en la tabla ASCII.

    • Conversión de entero a caracter (chr): La función caracter (char) de un valor entero devuelve el caracter correspondiente de la tabla ASCII.

    Ejemplos:

    ord (chr (i)) = i, si " chr(i)

    chr (ord (i)) = i

    • Tipos booleano

  • Conjunto de valores asociados con cierto y falso como dos únicos valores posibles.

  • { cierto, falso }

  • El tipo booleano es un tipo escalar y ordinal. Se asume que falso < cierto.

  • Operadores. Carece de operadores aritméticos, pero añade un tipo de operadores exclusivo del tipo booleano.

    • Booleanos: AND, OR, NOT.

    • Relacionales: <, ", =, ", ", >

    • Ordinales: pred, succ, ord.

  • Implementación. Para su representación se basa en los enteros 0 y 1, para los valores falso y cierto respectivamente.

  • 2.2.2.- Tipos definidos por el usuario

    Son subconjuntos de tipos ordinales, por tanto, también son ORDINALES. Dentro de esta clase encontramos los tipos enumerados y los subrangos; tipos normalizados.

    Ejemplo: Menú de selección de un cajero automático.

    Tenemos 6 opciones posibles a elegir. Podríamos usar un tipo entero, pero seguidamente se verá que es más adecuado y ajustado definirse un tipo enumerado o un subrango.

    opcion = 1..6; {definición por subrango}

    opcion = (1,2,3,4,5,6); {definición por enumerado} Dos posibles declaraciones de tipo

    a:opcion; {declaración de la variable}

    ... ... ...

    write('Escoge una opción');

    readln(a);

    ... ... ...

    • Tipo enumerado

    Se define un tipo enumerado mediante identificadores (los valores que queremos que formen el tipo).

    <nombre_tipo>=(<id_1>, <id_2>, ..., <id_n>);

    Ejemplos:

    diasemana=(lunes,martes,miercoles,jueves,viernes,sabado,domingo)

    colores=(verde,rojo,azul,amarillo)

    palos=(oros,copas,espadas,bastos)

    La implementación de un tipo enumerado se basa en el tipo ENTERO. El orden de la declaración es significativo para establecer las relaciones ordinales entre valores.

    miercoles > lunes; viernes < jueves

    ordinal(lunes)=0; ordinal(martes)=1

    OJO: Se trabaja con identificadores por tanto no se pueden leer del teclado ni escribir en la pantalla; es usual utilizar sentencias CASO.

    p:palos;

    CASO QUE p SEA

    oros:escribir('oros');

    copas:escribir('copas');

    espadas:escribir('espadas');

    bastos:escribir('bastos')

    OTRO CASO

    escribir('error')

    • Tipo Subrango

    Se define como subconjunto de otro tipo ORDINAL ya definido indicando un valor mínimo y un valor máximo. Formarán el tipo todos los valores comprendidos entre mínimo y máximo, incluídos éstos.

    <nombre> = Vmin ... Vmax

    Por ejemplo:

    opciones=1..6;

    alfabeto='A'..'Z';

    laborables=lunes..viernes;

    Los tipos subrango heredan las operaciones correspondientes al tipo sobre el que se definen (Ojo, si éste es enumerado!!).

    Peligro de desbordamiento

    x, y, z:opcionesM;

    ... ... ...

    x ! x+y;

    Probar esto para los casos en que x=1 y=4, y x=3 y=6 .

    Enumerados y subrango

    Son de utilidad como tipo índice. Los podemos usar como TI en los bucles PARA.

    PARA i ! 1 HASTA n HACER i"[1..n]

    PARA i ! 'A' HASTA 'L' HACER

    PARA i ! lunes HASTA miercoles HACER

    Los enumerados y subrangos pueden usarse para definir los elementos en los Tipo TABLA (ARRAYS):

    TABLA [1..n, 1..m] DE ...

    TABLA [Vmin .. Vmax] DE ...

    TIPO BASE: Llamaremos así a los tipos cuyos valores permitan construir una estructura de datos.

    2.3.- Tipos Estructurados

    Esta clase permite definir objetos que agrupan distintos valores. Estos valores pueden ser de tipo base u otro tipo estructurado. El lenguaje suele aportar las herramientas para manejar estos tipos, pero es el programador el que hará la definición concreta.

    Nos encontramos en el grupo de Tipos Estructurados a los vectores o tabla, cadenas, conjunto y registro. En los tres primeros los valores son de tipo base y en los registros podemos encontrarnos un tipo base u otro tipo estructurado en su interior.

    2.3.1.- Tipo Vector

    Caracterizamos el tipo estructurado vector por ser un conjunto finito y ordenado de elementos homogéneos. Nos referimos a sus elementos de la forma V[i]=x, donde V es el identificador del vector, i es de tipo índice e indica la posición i del elemento x dentro del vector V, y x es un conjunto de valores del mismo tipo base.

    Definición del Tipo Abstracto de Datos VECTOR

  • Operaciones:

    • Crear: ! vector

    • Extraer: vector x tipo_indice x ! tipo_base

    • Almacenar: vector x tipo_indice x tipo_base ! vector

    • Cuando se crea un vector el resultado es un nuevo vector cuyos elementos no están definidos.

    • La acción de extraer un elemento de un vector supone obtener un elemento de tipo base dados dicho vector y un índice i que indica la posición del elemento.

    • Para almacenar un elemento en una posición i determinada del vector tomaremos el valor del elemento tipo base a almacenar y obtendremos un nuevo valor del vector diferente del anterior.

  • Axiomas:

    • Extraer (Crear, i) = error

    si i=j x

    • Extraer (Almacenar (A, i, x), j) =

    sino Extraer (A, j)

    si i=j Almacenar (A, i, y)

    • Almacenar (Almacenar (A, i, x), j , y) =

    sino Almacenar (Almacenar (A, j, y), i, x)

  • Notación habitual:

  • TIPO

    • Crear (declaración del tipo vector) " vector=TABLA [Ti] DE Tb

    VARIABLES

    v:vector

    • Extraer (V, i) " V[i]

    • Almacenar (V, i, x) " V[i] ! x

    Un caso especial de tipo vector: CADENA

    Se representa como un vector de caracteres.

    <tipo>=TABLA [1..n] de CARÁCTER

    ó

    <tipo>=CADENA[n]

    La cadena admite todas las operaciones del vector y, además, y 4 exclusivas de las cadenas:

    • Subcadena: Cadena x TI x 1..n ! CADENA

    Dada la cadena C, un índice i y una longitud L (entre 1 y n), devolverá la subcadena englobada entre i é (i + L) de la cadena dada.

    • Posición: Cadena x Cadena ! 0..n

    Dadas las cadenas C1 y C2, devuelve la posición i a partir de la cual la cadena C2 está contenida en C1.

    • Longitud: Cadena ! 0..n

    Dada una cadena, devuelve su longitud.

    • Concatenar: CADENA x CADENA ! CADENA

    Dadas C1 y C2, el resultado es la cadena C=C1+C2 (C1 concatenado con C2).

    NOTA:

    El tipo CADENA admite la asignación simultánea de todos los valores.

    VARIABLES

    x:cadena;

    INICIO

    x ! `Hola buenos días'

    FIN.

    2.3.2.- Tipo CONJUNTO

    El tipo Conjunto es un estructurado con un número finito de elementos homegéneos sin ninguna relación de orden entre ellos.

    Definición del Tipo Abstracto de Datos CONJUNTO

  • Operaciones:

    • Crear: ! Conjunto

    El resultado es un conjunto, cuyos elementos no están definidos.

    • Insertar: Conjunto x TB ! Conjunto

    Dado un conjunto y un valor de TB, se obtiene un nuevo conjunto formado al añadir ese valor al conjunto original.

    • Pertenencia: Conjunto x TB ! Booleano

    Dado un conjunto y un valor de TB, indica si dicho valor pertenece o no al conjunto.

    • Unión: Conjunto x Conjunto ! Conjunto

    Dados dos conjuntos, obtiene el “conjunto unión”.

    • Intersección: Conjunto x Conjunto ! Conjunto

    Dados dos conjuntos se obtiene el “conjunto intersección”.

    • Diferencia: Conjunto x Conjunto ! Conjunto

    Dados dos conjuntos obtiene la diferencia entre ambos.

    • Inclusión: Conjunto x Conjunto ! Booleano

    Dados dos conjuntos, devuelve verdad si el segundo está contenido en el primero.

    • Igualdad: Conjunto x Conjunto ! Booleano

  • Axiomas:

  • " S, S1, S2 " Tipo CONJUNTO

    " x, y " Tipo Base

    • Pertenencia (x, Crear) = falso

    Verdad si x=y

    • Pertenencia (x, Insertar (S, y)) =

    Pertenencia (x, S) si x"y

    • Unión (S, Crear) = S

    • Unión (S1, Insertar (S2, x)) = Unión (Insertar (S1, x),S2)

    • Diferencia (Crear, S) = Crear

    Diferencia (S1, S2) si x" S2

    • Diferencia (Insertar (S1, x), S2) =

    Insertar (Diferencia (S1, S2), x) si x " S2

    • Intersección (S1, S2) = Diferencia (S1, Diferencia (S1, S2))

    • Inclusión (S, Crear) = cierto

    Inclusión (S1, S2) si x"S1

    • Inclusión (S1, Insertar (S2, x)) =

    Falso si x"S1

    • Igualdad (S1, S2) = Inclusión (S1, S2) Y Inclusión (S2, S1)

    ¿ Cómo implementaremos los conjuntos?

    TIPO

    Crear <nombre> = CONJUNTO de <Tipo_Base>

    VARIABLES

    c: <nombre>

    Insertar: Dado un valor de tipo base, x, se genera [x] al insertarlo en el conjunto vacío creado. Para insertar el valor en un conjunto no vacío, s: s ! s + [x].

    Pertenencia: Tenemos un valor de tipo base, x, y un tipo conjunto, C. Para comprobar la pertenencia lo haremos mediante la siguiente expresión: x EN C.

    Unión: D ! A+B; siendo D el “conjunto unión” y A,B los conjuntos a unir. Todos de tipo conjunto.

    Diferencia: D ! A-B

    Intersección: D ! A*B

    Igualdad: A=B

    Inclusión: A"B; cierto si A es un subconjunto de B.

    Restricciones al TB

    El tipo base utilizado como elemento de un conjunto debe ser FINITO y ORDINAL. Quedan excluidos, por tanto, Reales y Enteros. Normalmente, definiremos el conjunto en función de un tipo enumerado o subrango.

    colores=(rojo, azul, blanco)

    colorines=CONJUNTO de colores

    conjsubrango=CONJUNTO de Vmin..Vmax

    • Conjunto Vacío: []

    • Construcción de conjuntos:

    • por extensión: C ! [x1, x2, x3]

    • elemento a elemento:

    C ! [];

    MIENTRAS NO condición HACER

    ... ... ...

    x ! ... {valor de TB}

    C ! C + [x]

    FINMIENTRAS

    ... ... ...

    • El único modo de manejar valores de un conjunto es mediante el test de pertenencia.

    Por ejemplo:

    INICIO {subrangos}

    C: CONJUNTO de Vmin .. Vmax; { ó sobre (rojo, negro, blanco)}

    i ! Vmin;

    enc ! falso;

    MIENTRAS (NO enc) Y (i"Vmax) HACER

    enc ! i EN C;

    SI (NO enc) i! i+1 FINSI

    FINMIENTRAS

    FIN.

    INICIO {enumerados}

    i ! rojo;

    enc ! falso;

    MIENTRAS (NO enc) Y (i"blanco) HACER

    enc ! i EN C

    SI (NO enc) i ! succ (i) FINSI

    FINMIENTRAS

    FIN.

    2.3.3.- Tipo REGISTRO

    Un registro es un conjunto de pares (x, id) donde id indica un identificador de campo y x el valor almacenado en dicho campo.

    Definición del REGISTRO como TAD

  • Operaciones:

    • Crear: ! Registro

    Devuelve un registro, cuyos campos no están definidos.

    • Extraer: Registro x idi ! TBi

    Dado un registro y un identificador de un campo i, devuelve el valor de TB almacenado en dicho campo.

    • Almacenari: Registro x idi x Tbi ! Registro

    Dado un registro, un identificador de campo y un valor de TB, devuelve un registro en el que el valor del campo indicado ha sido sustituido por el valor nuevo.

  • Axiomas:

  • "r " Tipo Registro

    "x, y " Tipo Base

    • Extraer (Crear, id) = error

    x si idi=idj

    • Extraerj (Almacenari (r, idi, x), idj) =

    Extraer (r, idj) si idi"idj

    • Almacenarj (Almacenari (r, idi, x), idj, y) =

    Almacenarj (r, idj, y) si idi=idj

    =

    Almacenari (Almacenarj (r, idj, y), idi, x) si idi"idj

    • Instrucción CON (" WITH en Pascal)

    Registro en memoria = dir.base y a continuación los valores de los campos, r.idi.

    • Implementación de las operaciones:

    TIPO

    Crear <nombre>=REGISTRO de

    <campo1>:TB1;

    <campo2>:TB2;

    <campo3>:TB3;

    ... ... ... ... ... ... ... ...

    <campok>:TBk

    FINREGISTRO;

    VARIABLES

    r:<nombre>

    Extraer (r, idi) " r.idi

    Almacenar (r, idi, x) " r.idi ! x

    • Ejemplo:

    TIPO

    Fecha=REGISTRO de

    día, mes, año: ENTERO

    FINREGISTRO;

    VARIABLES

    r:fecha


    INICIO {sin CON}

    r.día ! ... ;

    r.mes ! ... ;

    r.año ! ... ;

    SI (r.anyo>1980) ENTONCES

    r.día ! ...

    FIN.


    INICIO {con CON}

    CON r HACER

    día ! ... ;

    mes ! ... ;

    año ! ... ;

    SI (año>1980) ENTONCES

    día ! ...

    FINCON

    FIN.

    Registros en parte variable

    Parte fija

    Registro = Discriminante

    Parte Variable

    Ejemplo:

    TIPO

    Paciente=(hombre, mujer, niño);

    Hospital=REGISTRO de

    Edad:ENTERO;

    Nombre:CADENA;

    NSS:CADENA;

    Domicilio:CADENA;

    CASO p:paciente QUE

    Mujer:

    Ginecólogo:CADENA;

    Num_partos:ENTERO;

    Hombre:

    Andrologo:CADENA;

    Niño:

    Pediatra:CADENA;

    Vacunas:VECTOR

    FINCASO

    FINREGISTRO;

    VARIABLES

    Ocupación:TABLA [1..n] de Hospital;

    INICIO

    Leer (v[i].edad);

    Leer (v[i].nombre);

    Leer (v[i].NSS);

    Leer (v[i].domicilio);

    CASO v[i].p QUE

    Mujer:v[i].ginecólogo ! `...'

    ... ... ... ... ... ... ... ... ... ... ...

    FINCASO

    ... ... ... ... ... ... ... ... ... ... ... ...

    FIN.

    EN GENERAL,

    <tipobase_discriminante>= _______ (normalmente enumerado ó BOOLEANO);

    <tipo_registro>=REGISTRO DE

    id1:TB1;

    id2:TB2;

    ... ... ... ...

    idn:TBn;

    CASO (discriminante:<tipobase_discriminante>) QUE

    Valor1:

    id11:TB11;

    id12:TB12;

    ... ... ... ... ...

    id1k:TB1k;

    ... ... ... ... ... ...

    Valorq:

    idq1:TBq1;

    idq2:TBq2;

    ... ... ... ... ...

    idqp:TBqp

    FINCASO

    FINREGISTRO;

    Precauciones

    • Definir siempre primero el discriminante.

    • Asociado al uso de la instrucción CASO en el algoritmo que lo maneje.

    • Vector_Conjunto

    {¿Cuándo hay que usarlos?}

    • Registro

    TEMA 3: Estructura de Datos PILA. Punteros

  • El tipo PILA

  • Definición y ejemplos

  • Definición del TAD Pila

  • Implementación Estática del tipo PILA: Uso de Vectores

  • Gestión Dinámica de la memoria

  • Punteros

  • Implementación Dinámica del tipo PILA: Uso de Punteros

  • 3.1.- El tipo PILA

    La pila es una estructura de datos en la que solamente podemos acceder a su último elemento introducido (LIFO). A este último elemento lo llamamos TOPE de la Pila. A esta posición accederemos cuando queremos añadir o eliminar elementos en la pila.

    3.1.1.- Definición y ejemplos

    Una PILA es una estructura de datos ORDENADA y HOMOGÉNEA, en la que sólo podemos acceder a una posición llamada TOPE. Los elementos de una pila se añaden o eliminan siguiendo una política LIFO (Last IN, First OUT).

    La PILA es una estructura DINÁMICA, es decir, su tamaño varía según llevamos a cabo operaciones sobre ella. No tiene limitación (¡¡Teórica!!) de tamaño.

    Importancia de las pilas en Informática

    Program MAIN Procedure A1( ); Procedure A2 ( ); Procedure A3 ( );

    BEGIN BEGIN BEGIN BEGIN

    ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

    ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

    ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

    r-1: A1 ... ... ... s-1: A2 ... ... ... t-1: A3 ... ... ... ... ... ... ... ...

    s: ... ... ... ... ... ... s: ... ... ... ... ... ... t: ... ... ... ... ... ... ... ... ... ... ...

    ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... END.

    ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

    END. END. END.

    3.1.2.- Definición del TAD Pila

    TAD: PILA

    Operaciones

  • Crear: ! Pila {Crea una pila vacía}

  • Añadir: Pila x TipoBase ! Pila {Dada una pila p y un valor e de tipo base, devuelve la pila formada al añadir a p el nuevo elemento (en la posición siguiente a la del TOPE).

  • Borrar: Pila ! Pila {Dada una pila, devuelve el valor del elemento que ocupa el TOPE de la pila}

  • Tope: Pila ! TipoBase {Dada una pila, devuelve el valor del elemento que ocupa el TOPE de la pila}

  • PilaVacía: Pila ! Booleano {Dada una pila, devuelve cierto si está vacía y falso en el caso contrario.

  • Axiomas: "p " PILA, "e " TipoBase

  • PilaVacía (Crear) = cierto

  • PilaVacía (Añadir (p, e)) = falso

  • Borrar (Crear) =error

  • Borrar (Añadir (p, e)) = p

  • Tope (Crear) =error

  • Tope (Añadir (p, e)) = e

  • 3.1.3.- Implementación Estática del tipo PILA: Uso de vectores

    • Similitudes entre pila y vector.

    • Ordenados

    • Homogéneos

    • Diferencias entre pila y vector

    • En un vector hay accesos a todos los elementos y en una pila sólo es posible el acceso al tope.

    • Un vector es una estructura de tamaño fijo (para definirlo hay que indicar su número de elementos); una pila no tiene restricciones TEÓRICAS sobre su tamaño.

    • Como solución a la primera diferencia basta con restringir el acceso a sólo una posición en el vector.

    PILA:

  • Necesitamos un vector y una variable que funcione como tope.

  • Definiremos un registro con un vector en un campo, sobre el que simularemos la pila, y en el otro campo un tope.

    • En cuanto a la limitación de tamaño de un vector no podemos hacer nada. Tan sólo controlar que no se nos llene la pila y se produzca un desbordamiento.

    • Definición de la estructura

    CONSTANTES

    MaxElem = ... ; {nº máximo de elementos en la pila}

    TIPOS

    TipoPila = REGISTRO DE

    Elementos: TABLA [1..MaxElem] de TipoBase;

    Tope: 0 .. MaxElem

    FINREGISTRO;

    VARIABLES

    P: TipoPila;

    ALGORITMO Crear (SAL p:TipoPila);

    INICIO

    p.tope ! 0

    FIN.

    ALGORITMO PilaVacía (ENT p:TipoPila): BOOLEANO;

    INICIO

    PilaVacía ! (p.tope=0)

    FIN.

    ALGORITMO Tope (ENT p:TipoPila; SAL e:TipoBase; error:Booleano);

    INICIO

    SI PilaVacía (p) ENTONCES

    Error ! cierto

    SINO

    Error ! falso;

    E ! p.elementos [p.tope]

    FINSI

    FIN.

    ALGORITMO Borrar (E/S p:TipoPila; SAL error:Booleano);

    INICIO

    SI PilaVacía (p) ENTONCES

    Error ! cierto

    SINO

    Error ! falso;

    p.tope ! p.tope -1

    FINSI

    FIN.

    ALGORITMO Añadir (E/S p:TipoPila; ENT e:TipoBase);

    INICIO

    p.tope ! p.tope +1;

    p.elementos [p.tope] ! e

    FINSI

    {algoritmo añadir con control de pila llena}

    ALGORITMO Añadir (E/S p:TipoPila; ENT e:TipoBase; SAL error:Booleano);

    INICIO

    SI (p.tope=MaxElem) ENTONCES

    Error ! cierto

    SINO

    Error ! falso;

    p.tope ! p.tope +1;

    p.elementos [p.tope] ! e

    FINSI

    FIN.

    ALGORITMO PilaLlena (ENT p:TipoPila): BOOLEANO;

    INICIO

    PilaLlena ! (p.tope=MaxElem)

    FIN.

    3.2.- Gestión dinámica de la memoria

    Estructura estática

    En tiempo de COMPILACIÓN hay un tamaño fijo. En tiempo de EJECUCIÓN no hay operaciones sobre la estructura que permitan variar su tamaño. (Ej: Vector, Registro).

    • Por contra, la pila es DINÁMICA: las operaciones sobre la pila (Añadir, Borrar) afectan a su tamaño.

    3.2.1.- Los Punteros

    Los punteros son un tipo simple (como ENTERO, REAL, CARÁCTER ó BOOLEANO) que permite gestionar de forma dinámica la ocupación en la memoria.

    TIPO

    Puntero_Entero = Puntero a entero;

    Otro_Puntero = Puntero a Elemento;

    Elemento = REGISTRO de

    a, b: entero;

    c: cadena[10]

    FINREGISTRO;

    VARIABLES

    p, q: Puntero_Entero;

    r: Otro_Puntero;

    {p apunta a la primera posición de memoria en la que se almacena un valor de tipo entero}

    Cuando trabajamos con punteros al compilar

    • El compilador reserva espacio para variables de tipo puntero.

    • Como se sabe a qué apunta es posible tenerlo en cuenta en ejecución a la hora de realizar operaciones con ellos.

    Operaciones con PUNTEROS

    • Asignación:

    ¡Ojo! Sólo valores válidos:

    • o bien NIL, p ! NIL

    • o bien el valor de otro puntero

    ... ... ... ... ...

    variables

    p, q: puntero;

    inicio

    p ! q

    fin.

    {suponemos que el valor y el tipo de los dos punteros sean compatibles}

    • NEW(q):

    Es una llamada que resuelve el GESTOR de MEMORIA. Se necesita crear una variable de forma dinámica. El Gestor de Memoria “reserva” el espacio necesario para almacenarla. Devuelve sobre q la posición de memoria a partir de la cual me han reservado el espacio.

    • DISPOSE(q):

    Es una llamada que resuelve el gestor de memoria. Se libera memoria. El gestor de memoria “libera” el espacio de memoria suficiente para almacenar la variable que está siendo apuntada por q, a partir de la posición de memoria indicada por q. El valor de q, queda indefinido.

    3.2.2.- Implementación de la PILA mediante PUNTEROS

    El único acceso del que dispondremos en la PILA, será el puntero a la posición de memoria en la que se almacene el TOPE.

    TPila = Puntero a Elemento;

    Elemento = REGISTRO de

    info: tipobase;

    sig: TPila

    FINREGISTRO;

    ALGORITMO CrearPila (SAL p: TPila);

    INICIO

    p ! NIL

    FIN; {fin crearpila}

    ALGORITMO PilaVacía (ENT p: TPila): Booleano;

    INICIO

    PilaVacía ! (p=NIL)

    FIN; {fin pilavacia}

    ALGORITMO Añadir (E/S p: TPila; ENT i: tipobase);

    VARIABLES

    q: TPila;

    INICIO

    NEW(q);

    q^.info ! i;

    q^.sig ! p;

    p ! q

    FIN; {fin añadir}

    ALGORITMO Borrar (E/S p: TPila; SAL e: booleano);

    VARIABLES

    q: TPila;

    INICIO

    SI PilaVacía (p) ENTONCES

    e ! cierto

    SINO

    e ! falso;

    q ! p;

    p ! p^.sig;

    DISPOSE (q)

    FINSI

    FIN; {fin borrar}

    ALGORITMO Tope (ENT p: TPila; SAL i: tipobase; error: booleano);

    INICIO

    error ! CIERTO;

    SI NO(PilaVacia (p)) ENTONCES

    error ! FALSO;

    i ! p^.info

    FINSI

    FIN; {fin tope}

    Comparación de ambas implementaciones

    • Memoria estática (vectores)

    Pegas:

    • se trabaja con una estructura de tamaño fijo.

    • problemas de PILA LLENA.

    • problemas de desaprovechamiento de memoria.

    • Memoria dinámica (punteros)

    Pegas:

    • en general, el tamaño de cada elemento de la pila es mayor (hay que guardar además del valor de tipo base, el puntero al siguiente, ...).

    TEMA 4: Estructuras COLA y LISTA

    4.1.- El Tipo COLA

  • Definición y ejemplos

  • Definición como TAD

  • Ejemplos de implementación

  • 4.1.3.1.- Implementación del Tipo Cola con Vectores

    4.1.3.2.- Implementación del Tipo Cola mediante Punteros

    4.2.- El Tipo LISTA

  • Definición. El TAD Lista

  • Implementación Dinámica del Tipo Lista

  • TAD's relacionados con el TAD Lista

  • 4.1.- El Tipo COLA

    4.1.1.- Definición y ejemplos

    Una Cola es un conjunto ordenado de elementos homegéneos (tipo base) en el cual, los elementos se eliminan por un punto determinado llamado cabeza, y se insertan por un punto llamado final. Esta estructura sigue la política FIFO (First IN, First OUT).

    Es una estructura dinámica puesto que su tamaño varía al realizar operaciones sobre ella.

    Operaciones:

  • CrearCola: ! Cola

  • ColaVacía: Cola ! Booleano {Indica si una cola está o no vacía}

  • Cabeza: Cola ! TipoBase {Devuelve el valor del elemento situado en lo cabeza de la cola}

  • Encolar:

  • Desencolar:

  • Axiomas: "q " Cola, "i " TipoBase

  • ColaVacía (CrearCola (q)) = CIERTO

  • ColaVacía (Encolar (q,i)) =FALSO

  • Desencolar (CrearCola (q)) = error

  • SI ColaVacía (q) ENTONCES

  • Desencolar (Encolar (q, i)) = CrearCola (q)

  • SINO Encolar (Desencolar (q), i) FINSI;

  • Cabeza (CrearCola (q)) = error

  • SI ColaVacía (q) ENTONCES

  • Cabeza (Encolar (q, i)) = i

  • SINO Cabeza (q) FINSI;

    4.1.3.- Ejemplos de implementación

    • con Vectores

    • con Punteros

    4.1.3.1.- Implementación del Tipo Cola con Vectores

    CONSTANTE

    MAX= ... {Número máximo del elementos}

    TIPOS

    Tcola= REGISTRO DE

    datos: TABLA [1 .. MAX] de TipoBase;

    cabeza, final: 0 .. MAX

    FINREGISTRO;

    Ideas Básicas:

    • Condición ColaVacía es (q.cabeza = q.final)

    • La operación CABEZA tendría una pinta similar a:

    SI NO(ColaVacía (q)) ENTONCES

    i ! q.datos [q.cabeza +1]

    FINSI;

    • La operación Desencolar:

    SI NO(ColaVacía (q)) ENTONCES

    q.cabeza ! q.cabeza +1

    FINSI;

    • La operación Encolar:

    SI NO(ColaLlena (q)) ENTONCES

    q.final ! q.final + 1;

    q.datos [q.final] ! i

    FINSI;

    • Para optimizar la ocupación del vector sobre el que implemente la Cola ! Vector Circular.

    CONSTANTES

    N= ... ;{nº máximo de elementos}

    MAX= N-1;

    TIPOS

    Tcola= REGISTRO DE

    datos= TABLA [0 .. MAX] de TipoBase;

    cabeza, final= 0 .. MAX

    FINREGISTRO;

    q.cabeza ! (q.cabeza + 1) ! (q.cabeza + 1) MOD N

    0, 1, 2, ..., n-1, 0 ,1, ..., n+1, 0 , 1 ...

    ALGORITMO CrearCola (SAL q: Tcola);

    INICIO

    q.cabeza ! 0;

    q.final ! 0

    FIN;

    ALGORITMO ColaVacía (ENT q: Tcola): Booleano;

    INICIO

    ColaVacía ! (q.cabeza = q.final)

    FIN;

    ALGORITMO Cabeza (ENT q: Tcola; SAL i: tipobase; error: booleano);

    INICIO

    error ! CIERTO;

    SI NO( ColaVacía (q)) ENTONCES

    error ! FALSO;

    i ! q.datos [(q.cabeza +1) MOD N]

    FINSI

    FIN;

    ALGORITMO Desencolar (E/S q: Tcola; SAL error : booleano);

    INICIO

    error ! CIERTO;

    SI NO( ColaVacía (q)) ENTONCES

    error ! FALSO;

    q.cabeza ! (q.cabeza + 1) MOD N

    FINSI

    FIN;

    ALGORITMO Encolar (E/S q: Tcola; ENT i: tipobase; SAL error: booleano);

    INICIO

    error ! cierto;

    SI NO(ColaLlena (q)) ENTONCES

    error ! FALSO;

    q.final ! (q.final +1) MOD N;

    q.datos [q.final] ! i

    FINSI

    FIN;

    ALGORITMO ColaLlena (ENT q: Tcola):booleano;

    INICIO

    ColaLlena ! (q.cabeza = ((q.final +1) MOD N))

    FIN;

    4.1.3.2.- Implementación del Tipo Cola mediante Punteros



    TipoPuntero = Puntero a ElemCola;

    ElemCola = REGISTRO DE

    info: <TB>;

    sig: TipoPuntero

    FINREGISTRO;

    Tcola = REGISTRO DE

    cabeza, final: TipoPuntero;

    {longitud: ENTERO}

    FINREGISTRO;


    ALGORITMO CrearCola (SAL q:TCola);

    INICIO

    q.cabeza ! NIL;

    q.final ! NIL;

    {q.longitud ! 0}

    FIN; {fin crearcola}

    ALGORITMO ColaVacía (ENT q: Tcola):Booleano;

    INICIO

    ColaVacía ! (q.cabeza=NIL Y q.final=NIL);

    {ColaVacía ! (q.longitud=0)}

    FIN; {fin colavacia}

    ALGORITMO Cabeza (ENT q: Tcola; SAL i: <TB>; error: Booleano);

    INICIO

    error ! CIERTO;

    SI NO ColaVacía (q) ENTONCES

    error ! FALSO;

    i ! q.cabeza^.info

    FINSI

    FIN; {fin cabeza}

    Desencolar

    ALGORITMO Desencolar (E/S q: Tcola; SAL error: Booleano);

    VARIABLES

    aux: TipoPuntero;

    INICIO

    error ! CIERTO;

    SI NO ColaVacía (q) ENTONCES

    error ! falso;

    aux ! q.cabeza;

    q.cabeza ! q.cabeza^.sig;

    SI (q.cabeza=NIL) ENTONCES {sólo había 1 elemento}

    q.final ! NIL

    FINSI;

    DISPOSE (aux);

    {q.longitud ! q.longitud -1}

    FINSI

    FIN; {fin desencolar}

    Encolar

    ALGORITMO Encolar (E/S q: Tcola; ENT i: <TB>);

    VARIABLES

    aux: TipoPuntero;

    INICIO

    new (aux);

    aux^.info ! i;

    aux^.sig ! NIL;

    SI ColaVacía (q) ENTONCES

    q.cabeza !aux

    SINO

    q.final^.sig ! aux

    FINSI

    q.final ! aux;

    {q.longitud ! q.longitud +1}

    FIN; {fin encolar}

    4.2.- El Tipo LISTA

    4.2.1.- Definición. El TAD Lista

    Estructura ordenada y homogénea en la que cualquier elemento es accesible y en la que es posible añadir o eliminar elementos en cualquier posición. La lista es una estructura de datos dinámica.

    PILA COLA LISTA

    1 punto 2 puntos ninguna restricción

    Definiciones básicas para estas 3 estructuras.

    PILA " TOPE

    COLA " {CABEZA, FINAL}

  • listas simplemente enlazadas (cada elemento tiene acceso al siguiente).

  • listas doblemente enlazadas (cada elemento tiene acceso al siguiente y al anterior).

  • listas circulares (cada elemento tiene acceso al siguiente y el último al primero).

  • Otras posibles definiciones:

    PILA " {tope, longitud}

    COLA " {cabeza, final, longitud}

    LISTA " {primero, longitud}

    " {primero, último}

    " {primero, último, longitud}

    Una lista es una tripla (P, R, v) donde:

    • P es un conjunto de posiciones que almacenan los valores dentro de la estructura.

    • R es la relación de orden entre las posiciones.

    • v es la función que relaciona una posición don el valor almacenado en ella.

    TAD: LISTA

    Operaciones:

    • Contructivas

  • CrearLista: ! Lista

  • Almacenar: Lista x Tipobase ! Lista {puede ser al principio, al final o en cualquier posición de la lista}

    • Modificadoras

  • Insertar: Lista x Tipobase x Posición ! Lista {antes de la posición o después de la posición}

  • Borrar: Lista x Posición ! Lista

  • Modificar: Lista x Posición x Tipobase ! Lista

    • De acceso

  • Dato: Lista x Posición ! Tipobase

  • Longitud: Lista ! Entero

  • Siguiente: Lista x Posición ! Posición

  • ListaVacía: Lista ! Booleano

  • Primero: Lista ! Posición

  • Último: Lista ! Posición

  • Anterior: Lista x Posición ! Posición

  • Buscar: Lista x Tipobase ! Posición

  • ¿Qué tomaremos como tipo Posición?

    • Natural

    • O cualquier otro tipo que sirva para referenciar elementos; por ejemplo un PUNTERO.

    CONJUNTO

    COLA

    PILA

    Contructivas

    Crear

    Crear

    Crear

    Insertar

    Encolar

    Añadir

    Modificadoras

    Unión

    Desencolar

    Borrar

    Diferencia

    Intersección

    De Acceso

    Pertenencia

    ColaVacía

    PilaVacía

    Inclusión

    Cabeza

    Tope

    Igualdad

    CONVENIOS (para los axiomas)

    • CrearLista, crea una lista nueva.

    • Almacenar, siempre añade el nuevo valor al final.

    • Insertar, inserta el nuevo valor antes del elemento indicado por posición.

    • Buscar, devuelve la posición del primer elemento cuyo valor coincida con el dado.

    4.2.2.- Implementación dinámica del tipo LISTA

    TIPO

    POSICIÓN= PUNTERO a Elemento;

    Elemento= REGISTRO DE

    info: tipobase;

    sig: POSICIÓN

    FINREGISTRO;

    TLISTA= POSICIÓN;

    {implementación alternativa}

    TLISTA= REGISTRO DE

    primero, último: POSICIÓN;

    longitud: Entero

    FINREGISTRO;

    ALGORITMO CrearLista (SAL l: Tlista);

    INICIO

    l.primero ! NIL;

    l.último ! NIL;

    l.longitud ! 0

    FIN; {fin crearlista}

    ALGORITMO Dato (ENT l: Tlista; p: posición; SAL i: tipobase);

    INICIO

    i ! p^.info

    FIN; {fin dato}

    {sin asumir NO error}

    ALGORITMO Dato (ENT l:Tlista; p: posición; SAL i: tipobase; error: booleano);

    VARIABLES

    aux: posición;

    INICIO

    aux ! l.primero;

    MIENTRAS (aux " p) Y (aux^.sig " NIL) HACER

    aux ! aux^.sig

    FINMIENTRAS;

    SI (aux = p) ENTONCES

    i ! p^.info

    SINO error

    FINSI

    FIN; {fin dato}

    ALGORITMO Longitud (ENT l: Tlista): Entero;

    INICIO

    longitud ! l.longitud

    FIN; {fin longitud}

    ALGORITMO Siguiente (ENT l: Tlista; p: posición): Posición;

    INICIO

    siguiente ! p^.sig

    FIN; {fin siguiente}

    ALGORITMO ListaVacía (ENT l: Tlista): Booleano;

    INICIO

    ListaVacía ! (Longitud (l) = 0)

    FIN; {fin listavacia}

    ALGORITMO Primero (ENT l: Tlista): Posición;

    INICIO

    Primero ! l.primero

    FIN; {fin primero}

    ALGORITMO Último (ENT l:Tlista): Posición;

    INICIO

    Último ! l.último

    FIN; {fin ultimo}

    ALGORITMO Anterior (ENT l:Tlista; p: posición): Posición;

    VARIABLES

    aux: posición;

    INICIO

    SI (p=primero(l)) ENTONCES

    aux ! NIL

    SINO

    aux ! primero(l);

    MIENTRAS (siguiente(l.aux) " p) HACER

    aux ! siguiente (l.aux)

    FINMIENTRAS

    FINSI;

    Anterior ! aux

    FIN; {fin anterior}

    ALGORITMO Buscar (ENT l:Tlista; i: tipobase): Posición;

    VARIABLES

    aux: posición;

    x: tipobase;

    INICIO

    aux ! primero (l);

    dato (l, aux, x);

    MIENTRAS (x " i) HACER

    aux ! siguiente (l, aux);

    dato (l, aux, x)

    FINMIENTRAS;

    Buscar ! aux

    FIN; {fin buscar}

    ALGORITMO Almacenar (E/S l:Tlista; ENT i:tipobase);

    VARIABLES

    aux: posición;

    INICIO

    new (aux);

    aux^.inf ! i;

    SI ListaVacía (l) ENTONCES

    l.primero ! aux

    SINO

    l.último^.sig ! aux

    FINSI;

    aux^.sig ! NIL;

    l.último ! aux;

    l.longitud ! l.longitud + 1

    FIN; {fin almacenar}

    ALGORITMO Insertar (E/S l: Tlista; ENT p: posición; i: tipobase);

    VARIABLES

    aux1, aux2: posición;

    INICIO

    new (aux1);

    aux1^.inf ! i;

    SI ListaVacía (l) ENTONCES

    l.primero ! aux1;

    l.último ! aux1; Almacenar (l, i)

    aux1^.sig ! NIL

    SINO

    SI (p=primero(l)) ENTONCES

    aux1^.sig ! primero (l);

    l.primero ! aux1;

    SINO

    aux2 ! Anterior (l, p);

    aux2^.sig ! aux1;

    aux1^.sig ! p

    FINSI

    FINSI

    { SI (p=primero(l)) ENTONCES

    l.primero ! aux1

    SINO

    aux2 ! Anterior (l, p);

    aux2^.sig ! aux1

    FINSI

    aux1^.sig ! p }

    l.longitud ! l.longitud + 1

    FIN; {fin insertar}

    ALGORITMO Borrar (E/S l:Tlista; ENT p:posición);

    VARIABLES

    aux: posición;

    INICIO

    SI (p=primero(l)) ENTONCES

    l.primero ! siguiente (l, p);

    SI (primero(l) = NIL) ENTONCES

    l.último ! NIL

    FINSI

    SINO

    aux ! Anterior (l, p);

    aux^.sig ! siguiente (l, p);

    SI (p=último(l)) ENTONCES

    l.último ! aux

    FINSI

    FINSI

    Dispose(p);

    l.longitud ! l.longitud - 1

    FIN; {fin borrar}

    ALGORITMO Modificar (E/S l:Tlista; ENT p: posición; i: tipobase);

    INICIO

    p^.inf ! i

    FIN; {fin modificar}

    4.2.3.- TAD's relacionados con el TAD Lista

  • TAD Lista Ordenada

  • Definición: Estructura lineal, homegénea y ordenada en la que podemos acceder a todos los elementos aunque teniendo en cuenta que estos siempre permanecerán ordenados según algún criterio.

    Operaciones: Las mismas que en el TAD lista con las siguientes excepciones,

    • Las opreaciones Almacenar e Insertar son substituidas por una llamada InsertarOrdenado (cada elemento se añade en su sitio).

    • No hay operación Modificar.

    • Ejemplo de implementación de InsertarOrdenado con el tipo base ENTERO:

    ALGORITMO InsertarOrdenado (E/S l: Tlista; ENT i: entero);

    VARIABLES

    aux1, aux2, aux: posición;

    INICIO

    new (aux1);

    aux1^.info ! i;

    SI ListaVacía (l) ENTONCES

    l.primero ! aux1;

    l.último !aux1;

    aux1^.sig ! NIL

    SINO

    SI (i<Dato(l, primero(l)) ENTONCES

    aux1^.sig ! primero (l);

    l.primero ! aux1;

    SINO

    aux2 ! primero (l);

    MIENTRAS (i>Dato(l, aux2) Y (aux " último(l)) HACER

    aux ! aux2;

    aux2 ! siguiente (l, aux2)

    FINMIENTRAS

    SI (Dato(l, aux2) " i) ENTONCES

    aux1^.sig ! aux2;

    aux^.sig ! aux1

    SINO

    aux1^.sig ! NIL;

    l.último^.sig ! aux1;

    l.último ! aux1

    FINSI

    FINSI

    FINSI

    l.longitud ! l.longitud + 1

    FIN; {fin insertarordenado}

  • TAD Lista de Listas

  • Definición: Una lista en la que el tipo base (sus elementos) es una lista.

    Operaciones: Las operaciones de este tipo serán las de la lista Tlista2 más las operaciones de la lista Tlista.

    En una lista de listas el elemento es una lista.

    • Almacenar en una Tlista2 supone:

    • Crear Tlista.

    • Almacenar elementos en Tlista.

    • Almacenar Tlista en Tlista2.

    • Borrar en Tlista2 supone:

    • Borrar todos los elementos en Tlista.

    • Borrar el elemento en Tlista2.

    • Modificar puede suponer:

    • Modificar toda una lista entero de tipo Tlista (elemento de Tlista2).

    • Modificar un elemento de una Tlista.

  • TAD Multilista

  • Definición: Lista Ordenada en la que existe más de un elemento siguiente y cada uno de ellos tiene un criterio de ordenación.

    Ejemplo:

    Elemento= REGISTRO DE

    titulo, asig CADENA;

    codigo: Entero

    FINREGISTRO;

    Posición= Puntero a ElementoMultiLista;

    ElementoMultiLista= REGISTRO DE

    info: Elemento;

    sigtit, sigasig, sigcod: Posición

    FINREGISTRO;

    MultiLista= REGISTRO DE

    primtit, primasig, primcod: Posición

    FINREGISTRO;

    TEMA 5: Introducción a las estructuras de datos NO Lineales. Árboles Binarios

    5.1.- Introducción

    5.2.- Árboles Binarios. Recorrido

    5.3.- Árboles Binarios de búsqueda

    5.1.- Introducción

    • Árbol: Cada elemento tiene un anterior y varios siguiente.

    • Grafo: Cada elemento tiene varios anteriores y varios siguientes.

    Usos de Árboles: Organización de la información.

    Además, esquemas algorítmicos

    • divide y vencerás

    • programación voraz

    • back tracking

    TERMINOLOGÍA BÁSICA

    • Nodo Padre de otro nodo A es el que apunta al nodo A.

    • Nodo Hijo de otro nodo A es el nodo que está siendo apuntado por el nodo A (cada nodo sólo tiene un padre y puede tener varios hijos).

    • Nodo Raíz es el primer nodo. No tiene nodo padre.

    • Nodo hoja hace referencia a cualquiera de los últimos nodos, es decir, un nodo que no tiene hijos.

    • Nodo interior es el que no es ni raíz ni hoja.

    • Camino es la secuencia de nodos en la que dos nodos consecutivos son padre e hijo. Un camino enlaza dos nodos.

    • Rama camino que va desde el nodo raíz a un nodo hoja.

    • Altura es el máximo número de nodos de cada una de las ramas.

    • Grado de un nodo es el número de hijos que tiene.

    • Grado de un árbol es el número máximo de hijos que puede tener un nodo.

    • Nivel de un nodo es el número de nodos del camino que va del nodo raíz a ese nodo.

    5.2.- Árbol Binario. Recorrido

    Un árbol binario es un árbol de grado 2. Pude ser un árbol vacío o estar formado por un nodo y 2 subárboles: izquierdo y derecho; también árboles binarios.

    Árbol Binario Equilibrado:

    Todos los nodos cumplen la siguiente propiedad,

    (altura (subarbolizquierdo) - altura (subarbolderecho)) " 1

    Árbol Binario Completo:

    Todos los nodos tienen dos hijos y todos los hijos están en el mismo nivel.

    nº de nodos en el nivel k = 2k-1

    nº de nodos total si la altura es h = 2n-1

    5.2.1.- TAD: Árbol Binario

    Operaciones:

  • CrearÁrbol: ! ÁrbolBinario {da como resultado un árbol binario vacío}

  • ConstruirÁrbol: ÁrbolBinario x nodos x ÁrbolBinario ! ÁrbolBinario

  • Ejemplo:

    <vacio> + 3 + <vacio> !

    (<vacio> + 3 + <vacio>) + 2 + <vacio> !

    A partir de dos árboles y un nodo de TipoBase se obtiene un nuevo árbol binario en el que cada uno de los árboles originales pasan a ser los subárboles izquierdo y derecho y el valor de tipobase se almacena en el NodoRaíz.

  • ÁrbolVacío: ÁrbolVacío ! Booleano

  • HijoDerecho: ÁrbolBinario ! ÁrbolBinario

  • HijoIzquierdo: ÁrbolBinario ! ÁrbolBinario

  • DatoRaíz: ÁrbolBinario ! TipoBase

  • Axiomas: " a1, a2 " ÁrbolBinario, "n " TB

  • ÁrbolVacío ( CrearÁrbol) = cierto

  • ÁrbolVacío (ConstruirÁrbol (a1, n, a2)) = falso

  • HijoIzquierdo (CrearÁrbol) = error

  • HijoIzquierdo (ConstruirÁrbol (a1, n, a2)) = a1

  • HijoDerecho (CrearÁrbol) = error

  • HijoDerecho (ConstruirÁrbol (a1, n, a2)) = a2

  • DatoRaíz (CrearÁrbol) = error

  • DatoRaíz (ConstruirÁrbol (a1, n, a2)) = n

  • 5.2.2.- Implementación

    La implementación de árboles se hará exclusivamente con punteros.

    TArbol = Puntero a Nodo;

    Nodo = REGISTRO DE

    info: TipoBase;

    izq, der: TArbol

    FINREGISTRO;

    Para trabajar con un árbol tenemos que conocer el puntero al NodoRaíz del árbol.

    ALGORITMO CrearArbol (SAL a: TArbol);

    INICIO

    a ! NIL

    FIN;

    ALGORITMO ArbolVacio (ENT a: TArbol): Booleano;

    INICIO

    ArbolVacio ! (a=NIL)

    FIN;

    ALGORITMO ConstruirArbol (ENT hi, hd: TArbol; x: TB; SAL a: TArbol);

    INICIO

    New(a);

    a^.info ! x;

    a^.izq ! hi;

    a^.der ! hd

    FIN;

    ALGORITMO HijoIzquierdo (ENT a: TArbol; SAL hi: TArbol; error: Booleano);

    INICIO

    error ! cierto;

    SI NO(ArbolVacio (a)) ENTONCES

    error ! falso;

    hi ! a^.izq

    FINSI

    FIN;

    ALGORITMO HijoDerecho (ENT a: TArbol; SAL hd: TArbol; error: Booleano);

    INICIO

    error ! cierto;

    SI NO(ArbolVacio (a)) ENTONCES

    error ! falso;

    hd ! a^.der

    FINSI

    FIN;

    ALGORITMO DatoRaiz (ENT a: TArbol; SAL x: TipoBase; error: Booleano);

    INICIO

    error ! cierto;

    SI NO(ArbolVacio(a)) ENTONCES

    error ! falso;

    x ! a^.info

    FINSI

    FIN;

    {implementaciones complementarias sin control de error}

    ALGORITMO ConstruirArbol (ENT hi, hd: TArbol; x:TipoBase); TArbol;

    VARIABLES

    nuevo: TArbol;

    INICIO

    new (nuevo);

    nuevo^.info ! x;

    nuevo^.izq ! hi;

    nuevo^.der ! hd;

    ConstruirArbol ! nuevo

    FIN;

    ALGORITMO HijoIzquierdo (ENT a: TArbol): TArbol;

    INICIO

    HijoIzquierdo ! a^.izq

    FIN;

    ALGORITMO HijoDerecho (ENT a: TArbol): TArbol;

    INICIO

    HijoIzquierdo ! a^.der

    FIN;

    ALGORITMO DatoRaíz (ENT a: TArbol): TipoBase;

    INICIO

    DatoRaíz ! a^.info

    FIN;

    5.2.3.- Recorrido de un Árbol Binario

    Realizar un recorrido de un árbol equivale a realizar la operación que permite acceder una única vez a al información de cada uno de los nodos del árbol.

    • PREORDEN: Se accede a la información del NodoRaíz después a la de los nodos del subárbol izquierdo y dinalmente a la de los nodos del subárbol derecho.

    • INORDEN: Se accede a la información del los nodos del subárbol izquierdo, después a la información del NodoRaíz, y finalmente a la información del subárbol derecho.

    • POSTORDEN: Se accede a la información de los nodos del subárbol izquierdo, después a la información del los nodos del subárbol derecho y por último a la información del NodoRaíz.

    ALGORITMO PreOrden (ENT a: TArbol {...});

    VARIABLES

    {...}

    INICIO

    SI NO(ArbolVacio (a)) ENTONCES

    ...

    Procesar (DatoRaiz (a));

    PreOrden (HijoIzquierdo (a));

    PreOrden (HijoDerecho (a))

    ...

    { SINO

    }

    FINSI

    FIN;

    ALGORITMO InOrden (ENT a: TArbol {...});

    VARIABLES

    {...}

    INICIO

    SI NO(ArbolVacio (a)) ENTONCES

    ...

    InOrden (HijoIzquierdo (a));

    Procesar (DatoRaiz (a));

    InOrden (HijoDerecho (a))

    ...

    { SINO

    }

    FINSI

    FIN;

    ALGORITMO PostOrden (ENT a: TArbol {...});

    VARIABLES

    {...}

    INICIO

    SI NO(ArbolVacio (a)) ENTONCES

    ...

    PostOrden (HijoIzquierdo (a));

    PostOrden (HijoDerecho (a))

    Procesar (DatoRaiz (a));

    ...

    { SINO

    }

    FINSI

    FIN;

    ALGORITMO Imprimir_Pre (ENT a: TArbol);

    INICIO

    SI NO(ArbolVacio (a)) ENTONCES

    Escribir (DatoRaiz (a));

    Imprimir_Pre (HijoIzquierdo (a));

    Imprimir_Pre (HijoDerecho (a))

    FINSI

    FIN;

    ALGORITMO Imprimir_In (ENT a: TArbol);

    INICIO

    SI NO(ArbolVacio (a)) ENTONCES

    Imprimir_In (HijoIzquierdo (a));

    Escribir (DatoRaiz (a));

    Imprimir_In (HijoDerecho (a))

    FINSI

    FIN;

    ALGORITMO Imprimir_Post (ENT a: TArbol);

    INICIO

    SI NO(ArbolVacio (a)) ENTONCES

    Imprimir_Post (HijoIzquierdo (a));

    Imprimir_Post (HijoDerecho (a))

    Escribir (DatoRaiz (a));

    FINSI

    FIN;

    5.3.- Árboles Binarios de búsqueda

    Definición:

    Árbol Binario en el que el valor de todos los elementos del subárbol izquierdo es menor o igual que el valor del elemento del nodoraíz que a su vez es menor que el valor de todos los elementos del subárbol derecho.

    Operaciones:

  • CrearArbol: ! TArbol

  • ArbolVacio: TArbol ! Booleano

  • BuscarNodo: TArbol x TipoBase ! TArbol

  • InsertarNodo: TArbol x TipoBase ! TArbol

  • EliminarNodo: TArbol x TipoBase ! TArbol

  • E4

    E3

    E2

    E1

    E1

    E2

    E3

    E4

    E5

    E4

    E3

    E2

    E1

    E1

    E2

    E3

    Tope=E3

    Tope=E4

    Tope=E4

    Tope=E5

    Borrar

    Borrar

    Añadir

    r

    r

    s

    r

    s

    t

    r

    s

    E4

    r

    E3

    E2

    E1

    tope

    E1

    E2

    E3

    E1

    E2

    E3

    E4

    E1

    E2

    E3

    encolar

    desencolar

    cabeza

    cabeza

    cabeza

    fin

    fin

    fin

    valor4

    valor3

    valor2

    valor1

    long=4

    final

    cabeza

    cabeza

    fin

    v1

    v2

    v3

    fin

    cabeza

    v1

    aux

    aux

    LISTA "

    TOPE

    CABEZA

    FIN

    punto de acceso imprescindible

    lista simplemente enlazada " primero

    lista doblemente enlazada " cualquier elemento

    lista circular " cualquier elemento

    primero

    último

    longitud

    3

    7

    10

    15

    8

    i=8

    3

    2

    3




  • Descargar
    Enviado por:Antonio Vidal
    Idioma: castellano
    País: España

    Te va a interesar