tecnológico de estudios superiores de ecatepec · web viewen caso de necesitarse una combinación...

84
2011 Departamento de Tecnológico de Estudios Superiores de Ecatepec ESTRUCTURA DE DATOS Elaboró: LIC. Dora Araceli Cruz Huerta

Upload: others

Post on 11-Feb-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

2011

Departamentode

Licenciatura en Informática

Av. Valle del Mayo Esq. Av. Hank González Col. Valle de Anáhuac C.P. 55210 Ecatepec de Morelos, Edo. de México

Tecnológico de Estudios Superiores de Ecatepec

ESTRUCTURA DE DATOS

Elaboró: LIC. Dora Araceli Cruz Huerta

Page 2: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Tecnológico de Estudios Superiores de EcatepecDirección Académica

Subdirección de Estudios ProfesionalesLicenciatura en Informática

2

APUNTES DE LA ASIGNATURAESTRUCTURA DE DATOS

Por:

Lic. Cruz Huerta Dora Araceli.

Page 3: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

OBJETIVO:

El alumno aprenderá las principales estructuras de datos desde un punto de vista abstracto y las operaciones que se puedan realizar sobre ellas, aplicando en forma práctica los conceptos adquiridos mediante resolución de problemas.

TEMARIO

1.- TIPOS DE DATOS

1.1 Tipos de datos.1.1.1 Tipos de datos simples.1.1.1.1 Definición de bit, byte, carácter y palabra.1.1.1.2 Manipulación de bits.1.1.1.3 Representación de datos simples.1.1.2 Tipos de datos abstractos.1.2 Estructuras de datos.1.2.1 Definición.1.2.2 Clasificación.1.2.2.1 Lineales y no lineales.1.2.2.2 Dinámicas y estáticas.

2.- ESTRUCTURAS LINEALES

2.1 Arreglos.2.1.1 Definición.2.1.2 Unidimensionales.2.1.3 Bidimensionales.2.1.4 Multidimensionales.2.1.5 Resolución de problemas con arreglos.2.1.6 Clases para la implementación de arreglos.2.2 Pilas.2.2.1 Definición.2.2.2 Operaciones.2.2.3 Clases para la implementación de pilas.2.3 Colas.2.3.1 Definición.2.3.2 Tipos.2.3.2.1 Colas simples.2.3.2.2 Colas circulares.2.3.2.3 Colas dobles.2.3.3 Operaciones.2.3.4 Clases para la implementación de colas.

3

Page 4: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

3.- LISTAS ENLAZADAS

3.1 Listas enlazadas.3.1.1 Simples.3.1.2 Dobles.3.1.3 Circulares.3.1.4 Multilistas.3.1.5 Clases para la implementación de listas.

4.- ESTRUCTURAS NO LINEALES

4.1 Árboles.4.1.1 Definición.4.1.2 Representación en memoria de árboles.4.1.2.1 Árboles generales.4.1.2.2 Árboles binarios.4.1.3 Recorridos en un árbol binario.4.1.3.1 Preorden.4.1.3.2 Inorden.4.1.3.3 Posorden.4.1.4 Balanceo de árboles binarios.4.1.5 Clases para la implementación de árboles.4.2 Grafos.4.2.1 Definición.4.2.2 Tipos de grafos.4.2.3 Representación de grafos en memoria.4.2.4 Clases para la implementación de grafos.

4

Page 5: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

UNIDAD1 TIPOS DE DATOS

1.1 Tipos de datos.

El manejo de la información en cualquier lenguaje de programación se realiza mediante diferentes clases de datos. 

  Entero    (Integer) Números enteros sin parte decimal.

Carácter    (Char) Caracteres del código ASCIIBoleano (Boolean) Pueden contener los valores de falso o verdadero

Real Números que pueden incluir una parte decimal

Cadena (String) En una secuencia de caracteres que se trata como un solo dato.

Un programa debe ser capaz de manejar diferentes tipos de datos, como pueden ser números enteros, reales, caracteres, cadenas de caracteres, etc. Para lograr el manejo de toda esta información. Algunos de los más importantes se citan en seguida:

Tipos enteros

En esta categoría generalmente cuenta con 5 tipos diferentes, cada uno abarca un rango específico de valores y utilizan una diferente cantidad de memoria dependiendo de ese rango. Naturalmente el trabajar con rangos menores nos ofrece una mayor velocidad y menor espacio en memoria, pero si se utilizan enteros largos se cuenta con mayor presición. Los tipos de enteros en  son:

Tipo  Rango de valores que acepta Integer  (Entero) -32,768 a 32,767 Word     (Palabra) 0 a 65535 ShortInt  (Entero corto) -128 a 127 Byte  0 a 255 LongInt  (Entero largo) -2,147,483,648 a 2,147,483,648 

Al utilizar los tipos enteros es posible representar en el programa un número en formato hexadecimal, para hacer esto solo se le antepone el símbolo "$" al

5

Page 6: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

valor hexadecimal, al momento de visualizar dicho valor, o utilizarlo en alguna operación será como decimal casi siempre en todos los casos que se utilice.

Tipos reales

Los números reales son aquellos que cuentan con una parte decimal. En algunos lenguajes de programación se tienen varios tipos de datos reales, pero no se puede utilizar, más que el tipo real, en máquinas que no cuenten con un coprocesador matemático. Los tipos de datos reales son:

Tipo  Rango de valores que acepta Real  ) 2.9E-39 a 1.7E38Single  1.5E-45 a 3.4E38Double  5.0E-324 a 1.7E308Extended  1.9E-4851 a 1.1E4932Comp  -9.2E18 a 9.2E18

Los números reales deben llevar por fuerza al menos un dígito de cada lado del punto decimal así sea éste un cero. Como ejemplo, el número 5 debe representarse como: 5.0, el .5 como 0.5 , etc.

 En este tipo de datos se utiliza la notación científica, que es igual a la de las calculadoras, el dígito que se encuentra a continuación de la E representa la potencia a la que se elevará el número 10 para multiplicarlo por la cantidad a la izquierda de dicha E:

3.0E5 = 3.0 * 10^5 = 3.0 * 100000 = 300000  1.5E-4 = 1.5 * 10^-4 = 1.5 * 0.0001 = 0.00015 

Tipos carácter

Los caracteres son cada uno de los símbolos que forman el código ASCII.. Los caracteres se especifican entre apostrofes:

'a' </TD 'B' </TD '2' '#' 

El tipo Char es un tipo ordinal en algunos lenguajes de programación, esto quiere decir que sus elementos válidos siguen una secuencia ordenada de valores individuales. La secuencia de caracteres para este tipo corresponde al número del código ASCII, del 0 al 255.

6

Page 7: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Es posible accesar a cada uno de los caracteres utilizando un signo # antes de su valor correspondiente, por ejemplo, la letra A puede ser representada como #65, el retorno de carro, o enter, se representa como #13, y así cualquier carácter.

Tipo cadena

Las cadenas son secuencias de caracteres o arreglos que tienen una longitud máxima de 255 caracteres. Se definen entre apostrofes.  

  Nombre : Cadena;    Nombre = 'Ernesto Chávez'; 

 

La cadena 'Ernesto Chávez' es almacenada en la variable nombre definida como tipo cadena.

 El tamaño por defecto para un tipo string es de 255 caracteres, pero es posible definir uno mas pequeño utilizando el siguiente formato:

Variable : Cadena[Tamaño];

Donde Variable es la variable a definir y Tamaño es el número máximo de caracteres que podrá contener esa variable (naturalmente mayor a 0 y menor a 256).

 Es posible acceder a un solo carácter de una cadena utilizando inmediatamente después del nombre de la misma la posición del carácter encerrada entre corchetes. Por ejemplo:

Nombre : String[30];   {Permite un máximo de 30 caracteres en la variable} 

Nombre := 'Ernesto Chávez';  

Escribir (Nombre[5]);   {Visualiza el 5to carácter de la cadena}   

7

Page 8: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Tipos lógicos

Este tipo de datos tienen la peculiaridad de que solo pueden tomar dos tipos de datos: verdadero o falso, el verdadero puede ser representado por su nombre en inglés: True y el falso por False; también se representan por 1 y por 0 respectivamente.

El tipo está definido como Boolean.

Los datos lógicos tienen una enorme aplicación en la evaluación de ciertos procesos, así como en el control de flujo de los programas. 

1.1.1 Tipos de datos simples.

Los datos a procesar por una computadora se pueden clasificar en:

Simples Estructurados

La principal característica de los datos simples es que ocupan solo una casilla de memoria, por lo tanto una variable simple hace referencia a un único valor a la vez. Dentro de este grupo de datos se encuentran: enteros, reales, carácter, boleanos, enumerados y subrrango (los dos últimos no existen en algunos lenguajes de programación).

Los datos estructurados se caracterizan por el hecho de que con un nombre (Identificador de variable) se hace referencia a un grupo de casillas de memoria). Es decir, un dato estructurado tiene varios componentes. Cada uno de los componentes puede ser un dato simple o estructurado. Sin embargo los componentes básicos de cualquier dato estructurado son datos simples.

Todas las estructuras de datos constituyen un aspecto muy importante en la computación, estas son:

Arreglos. Registros. conjuntos.

8

Page 9: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

1.1.1.1 Definición de bit, byte, carácter y palabra.

Bit: es una síntesis de dos términos en inglés: Binary digit, que en español significan dígito binario, o lo que es lo mismo, número (dígito) con dos posibles valores (binario). El término surge de usar las dos primeras letras de Binary con la última de digit.: bit. Es la unidad de información más sencilla posible en el sistema binario.

Byte: Unidad de información que consta de 8 bits equivalente a un único carácter, como una letra, número o signo de puntuación.

Carácter: Es un elemento tomado de un conjunto de símbolos. Un ejemplo de un conjunto de símbolos es {0,1,2,3,4,5,6,7,8,9,A,B,C....Y,z,¡,-,+,*} en el cual se incluyen dígitos, los caracteres del alfabeto y algunos caracteres especiales. Un compilador de lenguaje reconoce un conjunto particular de caracteres.

Palabra: Conjunto de bits que, como unidad elemental, puede manipular una computadora. La longitud en bits de una palabra en una computadora puede ser de 8, 16, 32, etc., y depende del microprocesador de su unidad central de proceso.

1.1.1.2 Manipulación de bits.

Ahora el ser humano digitaliza su entorno. Pero, ¿qué significa digitalizar? Digitalizar es traducir información como textos, imágenes o sonidos, a un formato que puedan entender los microprocesadores, y éstos sólo están capacitados para manejar los valores unos y ceros. En efecto, para tu microprocesador todo lo que ves en estos momentos en la pantalla se maneja con unos o ceros. Esto es porque la computadora maneja un sistema binario, que se llama así porque sólo acepta dos valores (0 y 1).

Tal sencillez tiene su razón de ser: los microprocesadores son circuitos electrónicos plasmados en un material llamado silicio (algo parecido al vidrio) que procesan diminutos impulsos eléctricos, el más pequeño de los cuales es conocido por el nombre de bit.

Como impulso eléctrico, el microprocesador sólo puede detectar cuando un bit tiene carga eléctrica --su valor sería, en este caso, 1-- o cuando no la tienen --su valor sería 0 - En este ejemplo manejamos los valores unos y ceros de manera un tanto arbitraria, ya que la presencia o ausencia de carga eléctrica en un bit puede ser interpretada como una gran diversidad de valores: cierto y falso, hombre o mujer, T o J, etc.

La eficacia de las computadoras no se basa en la complejidad de su fundamento lógico, que como vimos se reduce a manejar dos posibles valores, sino de la velocidad con la que se aplica dicha lógica: los microprocesadores actuales pueden procesar varios millones de bits en un sólo segundo.

9

Page 10: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Un bit puede representar solamente dos valores. Dos bits, cuatro posibles valores y ocho bits 256 posibles combinaciones de unos y ceros. Una unidad de medida muy utilizada en la informática es el byte, que consiste en la agrupación de ocho bits.

Ejemplo de combinaciones posibles por número de bits

Posibles combinaciones de unos y ceros usando dos bits 4:

00, 01, 11, 10

Posibles combinaciones de unos y ceros usando ocho bits 256:

00000000, 00000001, 00000011, 00000111 […] 11111111

Usando grupos de 8 bits (es decir, bytes) es posible representar a todos los caracteres que conforman el abecedario, incluyendo las mayúsculas y los signos especiales, como el de moneda o los acentos, de tal suerte que cuando se oprime la "e" en el teclado, el microprocesador recibe un paquete de 8 bits con la siguiente combinación de valores:

Valor de la letra "e" minúscula en bits:

0 1 1 0 0 1 0 1

Pero si en cambio se presiona la misma tecla en mayúsculas, el paquete de bits que se estará mandando al microprocesador sería el siguiente:Valor de la letra "E" mayúscula en bits:

0 1 0 0 0 1 0 1

Mediante combinaciones de bits y bytes es posible representar una cantidad infinita de cosas: desde bibliotecas completas hasta juegos y películas, todo un universo de información que puede estar en diversas formas; textos, imágenes y sonidos.

Se dice que algunas computadoras tienen aritmética decimal en lugar de binaria. Cuatro bits proporcionan 16 combinaciones, utilizadas para los 10 dígitos de 0 a 9, con 6 combinaciones sin utilizar. El número 1944 se muestra abajo codificado en decimal y en binario, utilizando 16 bits en cada ejemplo:

Decimal: 0001 1001 0100 0100

binario: 0000011110011000

10

Page 11: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

1.1.1.3 Representación de datos simples.

Los datos que utilizan los programas se pueden clasificar en base a diferentes criterios. Uno de los más significativos es aquel que dice que todos los datos que utilizan los programas son simples o compuestos.

Un dato simple es indivisible (atómico), es decir, no se puede descomponer.

Ejemplo 1: Un año es un dato simple.

Año...: 2006

Un año se expresa con un número entero, el cual no se puede descomponer. Sin embargo, un dato compuesto está formado por otros datos.

Ejemplo 2: Una fecha es un dato compuesto por tres datos simples (día, mes, año).

Fecha: Día...: 30 Mes...: 11 Año...: 2006

Ejemplo 3: Otro ejemplo de dato simple es una letra.

Letra...: t

Una letra se representa con un carácter del alfabeto. Pero, cuando varias letras se agrupan, entonces se obtiene un dato compuesto por varios caracteres.

Ejemplo 4: Para formar un nombre de persona se utilizan varios caracteres.

Nombre...: Ana (dato compuesto por tres caracteres)

11

Page 12: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Clasificación de los tipos de datos simples

Los tipos de datos simples se clasifican en predefinidos y definidos por el programador. La clasificación completa es:

Figura. Clasificación de los tipos de datos simples en pseudocódigo.

Los tipos de datos simples predefinidos (estándares) son aquellos proporcionados por los lenguajes de programación. Pero, el programador también puede definir sus propios tipos de datos simples (subrangos y enumerados), los cuales se estudiarán más adelante.

Todos los datos simples son ordinales, excepto el dato de tipo real. Un dato ordinal es aquel que puede tomar por valor un elemento perteneciente a un conjunto en el que todo elemento tiene un predecesor y un sucesor, excepto el primero y el último. Por ejemplo, el valor 5, perteneciente al conjunto de los números enteros, tiene como predecesor al 4, y como sucesor al 6. Sin embargo, entre dos números reales siempre hay un número infinito de números.

1.1.2 Tipos de datos abstractos.

Un tipo de dato abstracto o TDA (también Tipo abstracto de datos o TAD) es un modelo matemático compuesto por una colección de operaciones definidas sobre un conjunto de datos para el modelo.

12

Page 13: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

> Introducción

En el mundo de la programación existen diversos lenguajes que se han ido creando con el paso del tiempo y que se han perfeccionado debido a las necesidades de los programadores de la época a la que pertenecen. Los primeros lenguajes de programación eran de tipo lineales, ya que un programa se recorría desde un punto marcado como Inicio hasta llegar a un punto Fin. Con el tiempo se fueron creando nuevos lenguajes y en nuestros días los más utilizados son los llamados “Orientados a Objetos”.

Los Lenguajes Orientados a Objetos (LOO) tienen la característica de que no son lenguajes lineales, sino que se forman de diversas funciones, las cuales son llamadas en el orden en que el programa mismo las pide o el usuario determina. Para entender mejor cómo funcionan los Lenguajes Orientados a Objetos, vamos a introducir un concepto fundamental en las Estructuras de Datos denominado Abstracción de Datos y que es parte importante de estos Lenguajes y de la manera en que funciona la mayoría del software comercial de nuestros días.

Historia

El concepto de tipo de dato abstracto (TDA, Abstract Data Types ), fue propuesto por primera vez hacia 1974 por John Guttag y otros, pero no fue hasta 1975 que por primera vez Liskov lo propuso para el lenguaje CLU.llina

Definición

Con mucha frecuencia se utilizan los términos “TDA” y “Abstracción de Datos” de manera equivalente, y esto es debido a la similitud e interdependencia de ambos. Sin embargo, es importante definir por separado los dos conceptos.

Como ya se mencionó, los Lenguajes de Programación Orientados a Objetos son lenguajes formados por diferentes métodos o funciones y que son llamados en el orden en que el programa lo requiere, o el usuario lo desea. La abstracción de datos consiste en ocultar las características de un objeto y obviarlas, de manera que solamente utilizamos el nombre del objeto en nuestro programa. Esto es similar a una situación de la vida cotidiana. Cuando yo digo la palabra “perro”, usted no necesita que yo le diga lo que hace el perro. Usted ya sabe la forma que tiene un perro y también sabe que los perros ladran. De manera que yo abstraigo todas las características de todos los perros en un solo término, al cual llamo “perro”. A esto se le llama ‘Abstracción’ y es un concepto muy útil en la programación, ya que un usuario no necesita mencionar todas las características y funciones de un objeto cada vez que éste se utiliza, sino que son declaradas por separado en el programa y simplemente se utiliza el término abstracto (“perro”) para mencionarlo.

En el ejemplo anterior, “perro” es un Tipo de Dato Abstracto y todo el proceso de definirlo, implementarlo y mencionarlo es a lo que llamamos Abstracción de Datos.

13

Page 14: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Vamos a poner un ejemplo real de la programación. Supongamos que en algún Lenguaje de Programación Orientado a Objetos un pequeño programa saca el área de un rectángulo de las dimensiones que un usuario decida. Pensemos también que el usuario probablemente quiera saber el área de varios rectángulos. Sería muy tedioso para el programador definir la multiplicación de ‘base’ por ‘altura’ varias veces en el programa, además que limitaría al usuario a sacar un número determinado de áreas.

Por ello, el programador puede crear una función denominada ‘Área’, la cual va a ser llamada el número de veces que sean necesitadas por el usuario y así el programador se evita mucho trabajo, el programa resulta más rápido, más eficiente y de menor longitud. Para lograr esto, se crea el método Área de una manera separada de la interfaz gráfica presentada al usuario y se estipula ahí la operación a realizar, devolviendo el valor de la multiplicación. En el método principal solamente se llama a la función Área y el programa hace el resto.

Al hecho de guardar todas las características y habilidades de un objeto por separado se le llama Encapsulamiento y es también un concepto importante para entender la estructuración de datos.

Caracterización

Un TDA está caracterizado por un conjunto de operaciones (funciones) al cual le denominaron usualmente como su interfaz pública y representan el comportamiento del TDA; mientras que la implementación como la parte privada del TDA está oculta al programa cliente que lo usa. Todos los lenguajes de alto nivel tienen predefinidos TDA; que son los tipos denominados simples y las estructuras predefinidas, y estos tienen sus interfaces públicas que incluyen las operaciones como la +, -, *, etc.

En un TDA no se necesita conocer como actúan tales operadores sobre la representación interna de los tipos definidos, que además, suele ser una implementación bastante dependiente de la máquina sobre la que trabaje el compilador. Lo interesante es que los lenguajes actuales nos van a permitir ampliar los TDA predefinidos con otros que serán definidos por el propio programador para adecuar así los tipos de datos a las necesidades de los programas.

Los TDA que nos van a interesar de ahora en adelante son aquellos que reflejen cierto comportamiento organizando cierta variedad de datos estructuradamente. A esta forma estructurada de almacenar los datos será a la que nos refiramos para caracterizar cada TDA.

Los TDA que tienen informaciones simples pero dependientes de un comportamiento estructural serán llamados polilíticos y aquellos TDA simples, como son los tipos predefinidos donde la información no es relacionada mediante ninguna estructura y no admiten más que un valor en cada momento será denominados TDA monolíticos.

14

Page 15: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Nótese que cuando hablemos de un TDA no haremos ninguna alusión al tipo de los elementos sino tan sólo a la forma en que están dispuestos estos elementos. Sólo nos interesa la estructura que soporta la información y sus operaciones. Para determinar el comportamiento estructural basta con observar la conducta que seguirán los datos.

Caractericemos entonces los TDA. Un TDA tendrá una parte que será invisible al usuario la cual hay que proteger y que se puede decir que es irrelevante para el uso del usuario y está constituida tanto por la maquinaria algorítmica que implemente la semántica de las operaciones como por los datos que sirvan de enlace entre los elementos del TDA, es decir, información interna necesaria para la implementación que se esté haciendo para ese comportamiento del TDA. Resumiendo podemos decir, que tanto la implementación de las operaciones como los elementos internos del TDA serán privados al acceso externo y ocultos a cualquier otro nivel.

Un TDA representa una abstracción:

Se destacan los detalles (normalmente pocos) de la especificación (el qué).

Se ocultan los detalles (casi siempre numerosos) de la implementación (el cómo).

La abstracción

La abstracción, una de las herramientas que más nos ayuda a la hora de solucionar un problema, es un mecanismo fundamental para la comprensión de problemas y fenómenos que poseen una gran cantidad de detalles, su idea principal consiste en manejar un problema, fenómeno, objeto, tema o idea como un concepto general, sin considerar la gran cantidad de detalles que estos puedan tener. El proceso de abstracción presenta dos aspectos complementarios.

1.- Destacar los aspectos relevantes del objeto. 2.- Ignorar los aspectos irrelevantes del mismo (la irrelevancia depende del nivel de abstracción, ya que si se pasa a niveles más concretos, es posible que ciertos aspectos pasen a ser relevantes).

De modo general podemos decir que la abstracción permite establecer un nivel jerárquico en el estudio de los fenómenos, el cual se establece por niveles sucesivos de detalles. Generalmente, se sigue un sentido descendente de detalles, desde los niveles más generales a los niveles más concretos.

Por ejemplo: los lenguajes de programación de alto nivel permiten al programador abstraerse del sin fin de detalles de los lenguajes ensambladores. Otro ejemplo, la memoria de la computadora es una estructura unidimensional formada por celdas y sin embargo trabajamos como si fuera única.

15

Page 16: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

La abstracción nos brinda la posibilidad de ir definiendo una serie de refinamientos sucesivos a nuestro TDA y entiéndase bien que cuando decimos refinamientos sucesivos nos estamos refiriendo a la estrategia que se utiliza para descomponer un problema en subproblemas. Conforme evoluciona el diseño de software a cada nivel de módulos se representa un refinamiento en el nivel de abstracción. Esto es, incluir detalles que fueron obviados en un nivel superior, en un nivel más bajo de la jerarquía.

Veamos los diferentes tipos de abstracción que podemos encontrar en un programa:

1. Abstracción funcional: crear procedimientos y funciones e invocarlos mediante un nombre donde se destaca qué hace la función y se ignora cómo lo hace. El usuario sólo necesita conocer la especificación de la abstracción (el qué) y puede ignorar el resto de los detalles (el cómo).

2. Abstracción de datos:

Tipo de datos: proporcionado por los leguajes de alto nivel. La representación usada es invisible al programador, al cual solo se le permite ver las operaciones predefinidas para cada tipo.

Tipos definidos: por el programador que posibilitan la definición de valores de datos más cercanos al problema que se pretende resolver.

TDA: para la definición y representación de tipos de datos (valores + operaciones), junto con sus propiedades.

Objetos: Son TDA a los que se añade propiedades de reutilización y de compartición de código.

Si profundizamos más al mundo de la programación y sus conceptos, existen dos de estos conceptos que no se deben confundir, ellos son: tipo de datos y estructura de datos.

Un tipo de dato, en un lenguaje de programación, define un conjunto de valores que una determinada variable puede tomar, así como las operaciones básicas sobre dicho conjunto. Ahora veamos como se van relacionando estos conceptos. Los tipos de datos constituyen un primer nivel de abstracción, ya que no se tiene en cuenta cómo se implementan o se representan realmente la información sobre la memoria de la máquina. Para el usuario, el proceso de implementación o representación es invisible.

Veamos entonces que son las estructuras de datos. Las estructuras de datos son colecciones de variables, no necesariamente del mismo tipo, relacionadas entre sí de alguna forma. Las estructuras de datos están caracterizadas por el tipo de dato de los elementos guardados en la estructura y por la relación definida sobre estos elementos.

Al nivel de las estructuras de datos son totalmente irrelevantes las operaciones sobre un elemento en particular, solamente tienen carácter relevante las operaciones que envuelvan la estructura de forma global.Ejemplos de utilización de TDAs

16

Page 17: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Algunos ejemplos de utilización de TDAs en programación son:

Conjuntos: Implementación de conjuntos con sus operaciones básicas (unión, intersección y diferencia), operaciones de inserción, borrado, búsqueda...

Árboles: Implementación de árboles de elementos, utilizados para la representación interna de datos complejos.

Pilas y Colas: Implementación de los algoritmos FIFO y LIFO.

1.2 Estructuras de datos.

Como ya sabemos, las computadoras fueron diseñadas o ideadas como una herramienta mediante la cual podemos realizar operaciones de cálculo complicadas en un lapso de mínimo tiempo. Pero la mayoría de las aplicaciones de este fantástico invento del hombre, son las de almacenamiento y acceso de grandes cantidades de información.

La información que se procesa en la computadora es un conjunto de datos, que pueden ser simples o estructurados. Los datos simples son aquellos que ocupan sólo una localidad de memoria, mientras que los estructurados son un conjunto de casillas de memoria a las cuales hacemos referencia mediante un identificador único.

Debido a que por lo general tenemos que tratar con conjuntos de datos y no con datos simples (enteros, reales, booleanos, etc.) que por sí solos no nos dicen nada, ni nos sirven de mucho, es necesario tratar con estructuras de datos adecuadas a cada necesidad.

Las estructuras de datos son una colección de datos cuya organización se caracteriza por las funciones de acceso que se usan para almacenar y acceder a elementos individuales de datos.

Una estructura de datos se caracteriza por lo siguiente:

Pueden descomponerse en los elementos que la forman.

La manera en que se colocan los elementos dentro de la estructura afectará la forma en que se realicen los accesos a cada elemento.

La colocación de los elementos y la manera en que se accede a ellos puede ser encapsulada.

17

Page 18: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

1.2.1 Definición.

Una estructura de datos es una forma de organizar un conjunto de datos elementales (un dato elemental es la mínima información que se tiene en el sistema) con el objetivo de facilitar la manipulación de estos datos como un todo o individualmente.

Una estructura de datos define la organización e interrelacionamiento de estos, y un conjunto de operaciones que se pueden realizar sobre él. Las operaciones básicas son:

Alta, adicionar un nuevo valor a la estructura. Baja, borrar un valor de la estructura. Búsqueda, encontrar un determinado valor en la estructura para realizar

una operación con este valor, en forma SECUENCIAL o BINARIO (siempre y cuando los datos estén ordenados)...

Otras operaciones que se pueden realizar son:

Ordenamiento, de los elementos pertenecientes a la estructura. Apareo, dadas dos estructuras originar una nueva ordenada y que

contenga a las apareadas.

Cada estructura ofrece ventajas y desventajas en relación a la simplicidad y eficiencia para la realización de cada operación. De esta forma, la elección de la estructura de datos apropiada para cada problema depende de factores como la frecuencia y el orden en que se realiza cada operación sobre los datos.

1.2.2 Clasificación.

Datos simples

Binarios Bit Byte Numéricos Entero Real Coma fija Coma flotante Alfanuméricos Carácter Cadena

Estructuras de datos

Arrays (Arreglos) Vectores Matrices

Registro Tipo de datos algebraico Listas Enlazadas Listas Simples Listas Dobles Listas Circulares Listas por saltos (Skip lists) Pilas (stack) Colas (queue) Colas de Prioridad Árboles Árboles Binarios Árbol binario de búsqueda Árbol binario de búsqueda

autoajustable Árboles Rojo-Negro Árboles AVL

18

Page 19: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

1.2.2.1 Lineales y no lineales.

Las estructuras de datos simples se pueden combinar de varias maneras para formar estructuras más complejas. Las dos cases principales de estructuras de datos son las lineales y las no lineales, dependiendo de la complejidad de las relaciones lógicas que representan. Las estructuras de datos lineales incluyen pilas, colas y listas ligadas lineales. Las estructuras de datos no lineales incluyen grafos y árboles.

1.2.2.2 Dinámicas y estáticas.

Las estructuras de datos dinámicas:

No tienen las limitaciones o restricciones en el tamaño de memoria ocupada que son propias de las estructuras estáticas.

Mediante el uso de un tipo de datos especifico, denominado puntero, es posible construir estructuras de datos dinámicas que no son soportadas por la mayoría de los lenguajes, pero que en aquellos que si tienen estas características ofrecen soluciones eficaces y efectivas en la solución de problemas complejos.

Se caracteriza por el hecho de que con un nombre se hace referencia a un grupo de casillas de memoria. Es decir un dato estructurado tiene varios componentes.

Las estructuras de datos estáticas:

Son aquellas en las que el tamaño ocupado en memoria se define antes de que el programa se ejecute y no puede modificarse dicho tamaño durante la ejecución del programa.

Estas estructuras están implementadas en casi todos los lenguajes.

Su principal característica es que ocupan solo una casilla de memoria, por lo tanto una variable simple hace referencia a un único valor a la vez, dentro de este grupo de datos se encuentra: enteros, reales, caracteres, boléanos, enumerados y subrangos (los últimos no existen en algunos lenguajes de programación).

UNIDAD 2 ESTRUCTURAS LINEALES

19

Page 20: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

2.1 Arreglos.

Los arreglos se clasifican de acuerdo con el número de dimensiones que tienen. Así se tienen los:

- Unidimensionales (vectores)- Bidimensionales (tablas o matrices)- Multidimensionales (tres o más dimensiones)

2.1.1 Definición.

20

Page 21: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Un arreglo (array) es una colección de datos del mismo tipo, que se almacenan en posiciones consecutivas de memoria y reciben un nombre común. Para referirse a un determinado elemento de un array se deberá utilizar un índice, que especifique su posición relativa en el array. Un arreglo es una colección finita, homogénea y ordenada de elementos. Finita:Todo arreglo tiene un límite; es decir, debe determinarse cuál será el número máximo de elementos que podrán formar parte del arreglo. Homogénea: Todos los elementos del arreglo deben ser del mismo tipo. Ordenada: Se puede determinar cuál es el primer elemento, el segundo, el tercero,.... y el n-ésimo elemento.

2.1.2 Unidimensionales.

Están formados por un conjunto de elementos de un mismo tipo de datos que se almacenan bajo un mismo nombre, y se diferencian por la posición que tiene cada elemento dentro del arreglo de datos. Al declarar un arreglo, se debe inicializar sus elementos antes de utilizarlos. Para declarar un arreglo tiene que indicar su tipo, un nombre único y la cantidad de elementos que va a contener. Por ejemplo, las siguientes instrucciones declaran tres arreglos distintos:Float costo_partes[50];

21

Page 22: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Para acceder a valores específicos del arreglo, use un valor de índice que apunte al elemento deseado. Por ejemplo, para acceder al primer elemento del arreglo calificaciones debe utilizar el valor de índice 0 (calificaciones[0]). Los programas en C++ siempre indizan el primer elemento de un arreglo con 0 y el último con un valor menor en una unidad al tamaño del arreglo.

2.1.3 Bidimensionales.

Este tipo de arreglos al igual que los anteriores es un tipo de dato estructurado, finito ordenado y homogéneo. El acceso a ellos también es en forma directa por medio de un par de índices.

Los arreglos bidimensionales se usan para representar datos que pueden verse como una tabla con filas y columnas. La primera dimensión del arreglo representa las columnas, cada elemento contiene un valor y cada dimensión representa una relación.

La representación en memoria se realiza de dos formas: almacenamiento por columnas o por renglones.

Para determinar el número total de elementos en un arreglo bidimensional usaremos las siguientes fórmulas:

RANGO DE RENGLONES (R1) = Ls1 - (Li1+1)RANGO DE COLUMNAS (R2) = Ls2 - (Li2+1)No. TOTAL DE COMPONENTES = R1 * R2

REPRESENTACION EN MEMORIA POR COLUMNAS

x : array [1..5,1..7] of integer

Para calcular la dirección de memoria de un elemento se usan la siguiente formula:

A[i,j] = base (A) + [((j - li2) R1 + (i + li1))*w]

22

Page 23: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

REPRESENTACION EN MEMORIA POR RENGLONES

x : array [1..5,1..7] of integer

Para calcular la dirección de memoria de un elemento se usan la siguiente formula:

A[i,j] = base (A) + [((i - li1) R2 + (j + li2))*w]

Donde:

i = Índice del renglón a calcular j = Índice de la columna a calcular li1 = Límite inferior de renglones li2 = Límite inferior de columnas w = Número de bytes tipo componente

2.1.4 Multidimensionales.

Este también es un tipo de dato estructurado, que está compuesto por n dimensiones. Para hacer referencia a cada componente del arreglo es necesario utilizar n índices, uno para cada dimensión.

Para determinar el número de elementos en este tipo de arreglos se usan las siguientes fórmulas:

RANGO (Ri) = lsi - (lii + 1)No. TOTAL DE ELEMENTOS = R1 * R2* R3 * ...* Rn

Donde:

i = 1 ... n n = No. total de dimensiones

Para determinar la dirección de memoria se usa la siguiente formula:

LOC A[i1,i2,i3,...,in] = base(A) + [(i1-li1)*R3*R4*Rn + (i2-li2)*R3*R2*... (in - lin)*Rn]*w

2.1.5 Resolución de problemas con arreglos.

23

Page 24: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Las operaciones para la resolución de problemas en arreglos pueden clasificarse de la siguiente forma:

Lectura Escritura Asignación Actualización Ordenación Búsqueda

a) LECTURA

Este proceso consiste en leer un dato de un arreglo y asignar un valor a cada uno de sus componentes.

La lectura se realiza de la siguiente manera:

para i desde 1 hasta N hazx<--arreglo[i]

b) ESCRITURA

Consiste en asignarle un valor a cada elemento del arreglo.

La escritura se realiza de la siguiente manera:

para i desde 1 hasta N hazarreglo[i]<--x

c) ASIGNACION

No es posible asignar directamente un valor a todo el arreglo, por lo que se realiza de la manera siguiente:

para i desde 1 hasta N hazarreglo[i]<--algún_valor

d) ACTUALIZACION

Dentro de esta operación se encuentran las operaciones de eliminar, insertar y modificar datos. Para realizar este tipo de operaciones se debe tomar en cuenta si el arreglo está o no ordenado.Para arreglos ordenados los algoritmos de inserción, borrado y modificación son los siguientes:

24

Page 25: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

1.- Insertar.

Si i< mensaje(arreglo contrario caso En arreglo[i]<--valor i<--i+1 entonces>

2.- Borrar.

Si N>=1 entoncesinicio i<--1 encontrado<--falso mientras i<=n y encontrado=falso

inicio si arreglo[i]=valor_a_borrar entonces

inicio encontrado<--verdadero N<--N-1 para k desde i hasta N haz

arreglo[k]<--arreglo[k-1]fin

en caso contrarioi<--i+1

finfinSi encontrado=falso entonces

mensaje (valor no encontrado)

3.- Modificar.

Si N>=1 entonces inicio

i<--1encontrado<--falsomientras i<=N y encontrado=false haz inicio

Si arreglo[i]=valor entonces arreglo[i]<--valor_nuevo encontrado<--verdaderoEn caso contrario i<--i+1

fin fin

2.1.6 Clases para la implementación de arreglos.

25

Page 26: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Las clases de implementación de arreglos son un conjunto de caracteres incluido el espacio en blanco, que se almacena en un área contigua de la memoria central. La longitud de una cadena es el número de caracteres que contiene. Una cadena vacía es la que no tiene ningún carácter. Una constante de tipo cadena es un conjunto de caracteres válidos encerrados entre comillas. Una variable de cadena es aquella cuyo contenido es una cadena de caracteres. El último carácter de la cadena marca el fin de la cadena.

Las variables de cadena se dividen en:

· Estáticas. Su longitud se define antes de ejecutar el programa y no puede cambiarse a lo largo de este.

· Semiestáticas. Su longitud puede variar durante la ejecución del programa, pero sin sobrepasar un límite máximo declarado al principio.

· Dinámicas. Su longitud puede variar sin limitación dentro del programa.

Operaciones básicas con cadenas:

· Asignación.

Nombre ¬ "Luis Humberto"

· Entrada/ Salida

Leer(nombre, estado_civil)Escribir(nombre, apellido)Escribir(nombre, apellido)

2.2 Pilas.

Las pilas son otro tipo de estructura de datos lineales, las cuales presentan restricciones en cuanto a la posición en la cual pueden realizarse las inserciones y las extracciones de elementos. Una pila es una lista de elementos en la que se pueden insertar y eliminar elementos sólo por uno de los extremos. Como consecuencia, los elementos de una pila serán eliminados en orden inverso al que se insertaron. Es decir, el último elemento que se metió a la pila será el primero en salir de ella.

En la vida cotidiana existen muchos ejemplos de pilas, una pila de platos en una alacena, una pila de latas en un supermercado, una pila de papeles sobre un escritorio, etc.

Debido al orden en que se insertan y eliminan los elementos en una pila, también se le conoce como estructura LIFO (Last In, First Out: último en entrar, primero en salir).2.2.1 Definición.

26

Page 27: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Una pila (stack en inglés) es una estructura de datos de tipo LIFO (del inglés Last In First Out, último en entrar, primero en salir) que permite almacenar y recuperar datos. Se aplica en multitud de ocasiones en informática debido a su simplicidad y ordenación implícita en la propia estructura.

2.2.2 Operaciones.

Para el manejo de los datos se cuenta con dos operaciones básicas: apilar (push), que coloca un objeto en la pila, y su operación inversa, retirar (o desapilar, pop), que retira el último elemento apilado.

En cada momento sólo se tiene acceso a la parte superior de la pila, es decir, al último objeto apliado (denominado TOS, top of stack en inglés). La operación retirar permite la obtención de este elemento, que es retirado de la pila permitiendo el acceso al siguiente (apilado con anterioridad), que pasa a ser el nuevo TOS.

Por analogía con objetos cotidianos, una operación apilar equivaldría a colocar un plato sobre una pila de platos, y una operación retirar a retirarlo.

Las pilas suelen emplearse en los siguientes contextos:

Evaluación de expresiones en notación postfija (notación polaca inversa).

Reconocedores sintácticos de lenguajes independientes del contexto Implementación de recursividad.

2.2.3 Clases para la implementación de pilas.

El concepto de recursión es difícil de precisar, pero existen ejemplos de la vida cotidiana que nos pueden servir para darnos una mejor idea acerca de lo que es recursividad. Un ejemplo de esto es cuando se toma una fotografía de una fotografía, o cuando en un programa de televisión un periodista transfiere el control a otro periodista que se encuentra en otra ciudad, y este a su vez le transfiere el control a otro.Casos típicos de estructuras de datos definidas de manera recursiva son los árboles binarios y las listas enlazadas.

27

Page 28: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

La recursión se puede dar de dos formas:

DIRECTA. Este tipo de recursión se da cuando un subprograma se llama directamente a sí mismo.

INDIRECTA Sucede cuando un subprograma llama a un segundo subprograma, y este a su vez llama al primero, es decir el subproceso A llama al B, y el B invoca al subproceso A.

Otra de las aplicaciones en las que podemos utilizar las pilas es en la implementación de la recursividad. A continuación se mostrarán algunos ejemplos.

| | 1 , N=0Factorial < | N*(n-1)!, N&gt0 |

sp <--0 mientras n <> 1 haz push(pila,n) n<--n-1 mientras sp <> 0 haz factorial<--factorial*pop(pila)

| | 0 , si a < bQ < | Q(a-b,b)+1, si a<=b |

sp<--0 Q<--0 lee(a), lee(b) mientras a>=b haz push(pila,1) a<--a-b mientras sp< > 0 haz Q<-- Q + pop(pila)

2.3 Colas.

28

Page 29: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Una cola es una estructura de almacenamiento, donde la podemos considerar como una lista de elementos, en la que éstos van a ser insertados por un extremo y serán extraídos por otro.

Las colas son estructuras de tipo FIFO (first-in, first-out), ya que el primer elemento en entrar a la cola será el primero en salir de ella.

Existen muchísimos ejemplos de colas en la vida real, como por ejemplo: personas esperando en un teléfono público, niños esperando para subir a un juego mecánico, estudiantes esperando para subir a un camión escolar, etc.

2.3.1 Definición.

Una cola es una estructura de datos, caracterizada por ser una secuencia de elementos en la que la operación de inserción push se realiza por un extremo y la operación de extracción pop por el otro. También se le llama estructura FIFO (del inglés First In First Out), debido a que el primer elemento en entrar será también el primero en salir.

2.3.2 Tipos.

Colas de prioridad: En ellas, los elementos se atienden en el orden indicado por una prioridad asociada a cada uno. Si varios elementos tienen la misma prioridad, se atenderán de modo convencional según la posición que ocupen.

Hay 2 formas de implementación:

1 Añadir un campo a cada nodo con su prioridad. Resulta conveniente mantener la cola ordenada por orden de prioridad.

2 Crear tantas colas como prioridades haya, y almacenar cada elemento en su cola.

Bicolas: son colas en donde los nodos se pueden añadir y quitar por ambos extremos; se les llama DEQUE (Double Ended QUEue). Para representar las bicolas lo podemos hacer con un array circular con Ini y Fin que apunten a cada uno de los extremos. Hay variantes:

Bicolas de entrada restringida: Son aquellas donde la inserción sólo se hace por el final, aunque podemos eliminar al principio ó al final.

Bicolas de salida restringida: Son aquellas donde sólo se elimina por el final, aunque se puede insertar al principio y al final.

Colas de prioridad: son las que cumplen dos reglas:

29

Page 30: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

1 De dos elementos siempre se atenderá antes al que tenga mayor prioridad.

2 Si dos elementos tienen la misma prioridad se atiende primero el que llego antes.

Realización Se ponen todos los nodos en la misma cola. Su particularidad es que cada nodo tiene un campo adicional con la prioridad del dato; de tal forma que cuando insertamos nuevos datos, el nuevo nodo, se inserta al final de la cola de los que tengan su misma prioridad.

2.3.2.1 Colas simples.

Esta significa el primero en llegar es el primero en salir. La estructura de este es como cualquier tipo de fila como: la cola que tienes que hacer en un lugar esperando a ser atendido y como todos sabemos, el primero en llegar estará en frente de la cola y será el primero en salir.

In- Sirve para ingresar los valores que se van agregando, este valor será el primero en la cola y se quedara con el apuntador externo "front", los demás serán parte de la cola y el ultimo que este en la cola será apuntado por el apuntador externo "end".

Algoritmo:

1. inicio manda a llamar in 2. estado de cola?

Vacía =3

sino =8

3. crear nodo

4. asignación de valor

5. los apuntadores externos "end" y "front" apuntan al nuevo nodo

6. el apuntador interno "next" del nuevo nodo apunta a nulo

7. fin

30

Page 31: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

8. crear nodo

9. asignación de valor

10. el apuntador externo "nuevo" asigna al apuntador interno "next" del nodo del nuevo valor apuntar al nodo que esta apuntando el apuntador externo "end".

11. el apuntador externo "end" se actualiza moviéndose al nuevo nodo

12. el apuntador externo "end" asigna al apuntador interno "next" apuntar a nulo

13. fin

Para el algoritmo #7 el diseño de la estructura seria:

Para el algoritmo #13 el diseño de la estructura seria:

Out- Sirve para sacar el primer valor que fue ingresado. Si hay solo un valor en la estructura, simplemente ya no hay mas valores en la pila. Si se intenta sacar un valor cuando no hay valores se avisara que no hay valores.

31

Page 32: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Algoritmo:

1. inicio manda a llamar a out 2. estado de cola?

Vacía =3

Solo 1 valor =5

Sino =7

3. mensaje "no hay valores en la pila

4. fin 5. se muestra el valor por borrar y los apuntadores externos "end" y "front" serán nulos

6. fin 7. se muestra el valor por borrar y se inicializa un ciclo para desconectar el primer valor y

hacer el segundo como primero.

8. y para eso el apuntador externo "front" se actualiza con al ayuda del apuntador externo "aux" y asigna al apuntador interno "next" apuntar a nulo

9. fin

Para el algoritmo #6 el diseño de la estructura seria:

32

Page 33: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Para el algoritmo #7 el diseño de la estructura seria:

 

Para el algoritmo #9 el diseño de la estructura seria:

El segundo que este se queda con el apuntador externo "front" y el primer valor, antes de que se hiciera el pop, se desconecta de la estructura.

Todo esto es un proceso de programación muy delicada ya que con cualquier mal asignación de apuntadores, tanto internos como externos, puede arruinar la estructura de los valores y hasta perder la información.

33

Page 34: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

2.3.2.2 Colas circulares.

Las colas lineales tienen un grave problema, como las extracciones sólo pueden realizarse por un extremo, puede llegar un momento en que el apuntador A sea igual al máximo número de elementos en la cola, siendo que al frente de la misma existan lugares vacíos, y al insertar un nuevo elemento nos mandará un error de overflow (cola llena).

Para solucionar el problema de desperdicio de memoria se implementaron las colas circulares, en las cuales existe un apuntador desde el último elemento al primero de la cola.

La representación gráfica de esta estructura es la siguiente:

La condición de vacío en este tipo de cola es que el apuntador F sea igual a cero.

Las condiciones que debemos tener presentes al trabajar con este tipo de estructura son las siguientes:

Over flow, cuando se realice una inserción. Under flow, cuando se requiera de una extracción en la cola. Vacio

ALGORITMO DE INICIALIZACIÓN

F < -- 0A<-- 0

ALGORITMO PARA INSERTAR

Si (F+1=A) ó (F=1 y A=máximo) entonces mensaje (overflow)en caso contrario inicio

si A=máximo entonces A<--1 cola[A]<-- valoren caso contrario A <--A+1 cola[A]<-- valorsi F=0 entonces F <-- 1

fin

ALGORITMO PARA EXTRAER

34

Page 35: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Si F=0 entonces mensaje (underflow)en caso contrario x <-- cola[F] si F=A entonces

F <-- 0A<-- 0

en caso contrariosi F=máximo entonces F <--1 en caso contrario F <-- F+1

2.3.2.3 Colas dobles.

Esta estructura es una cola bidimensional en que las inserciones y eliminaciones se pueden realizar en cualquiera de los dos extremos de la bicola. Gráficamente representamos una bicola de la siguiente manera:

Existen dos variantes de la doble cola:

Doble cola de entrada restringida. Doble cola de salida restringida.

La primer variante sólo acepta inserciones al final de la cola, y la segunda acepta eliminaciones sólo al frente de la cola

ALGORITMOS DE ENTRADA RESTRINGIDA

Algoritmo de Inicialización

F < -- 1A <-- 0

Algoritmo para Insertar

Si A=máximo entonces mensaje (overflow)en caso contrario A <--A+1 cola[A]<-- valor

Algoritmo para Extraer

35

Page 36: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Si F&gtA entonces mensaje (underflow)en caso contrario mensaje (frente/atrás)

si frente entonces x <-- cola[F] F <-- F+1en caso contrario x <-- cola[A] A <-- A-1

ALGORITMOS DE SALIDA RESTRINGIDA

Algoritmo de Inicialización

F <--1A <-- 0

Algoritmo para Insertar

Si F&gtA entonces mensaje (overflow)en caso contrario mensaje (Frente/Atrás) si Frente entonces

cola[F] <--valor en caso contrario

A <-- A+1cola[A] <--valor

Algoritmo para Extraer

Si F=0 entonces mensaje (underflow)en caso contrario x <--cola[F] F <-- F+1

2.3.3 Operaciones.

Las operaciones que nosotros podemos realizar sobre una cola son las siguientes:

Inserción.

Extracción.

36

Page 37: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Las inserciones en la cola se llevarán a cabo por atrás de la cola, mientras que las eliminaciones se realizarán por el frente de la cola (hay que recordar que el primero en entrar es el primero en salir).

2.3.4 Clases para la implementación de colas.

Esta implementación es estática, es decir, da un tamaño máximo fijo a la cola. No se incluye comprobación de errores dentro del encolado y el desencolado, pero se implementan como funciones aparte.

¿Por qué un array circular? ¿Qué es eso? Como se aprecia en la implementación de las pilas, los elementos se quitan y se ponen sobre la cima, pero en este caso se introducen por un sitio y se quitan por otro.

Podría hacerse con un array secuencial, como se muestra en las siguientes figuras. 'Entrada' es la posición de entrada a la cola, y 'Salida' por donde salen.

En esta primera figura se observa que se han introducido tres elementos: 3, 1 y 4 (en ese orden):

se desencola, obteniendo un 3:

se encola un 7:

Enseguida se aprecia que esto tiene un grave defecto, y es que llega un momento en el que se desborda la capacidad del array. Una solución nada efectiva es incrementar su tamaño. Esta implementación es sencilla pero totalmente ineficaz.

Como alternativa se usa el array circular. Esta estructura nos permite volver al comienzo del array cuando se llegue al final, ya sea el índice de entrada o el índice de salida.

37

Page 38: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

UNIDAD 3 LISTAS ENLAZADAS

3.1 Listas enlazadas.

Una lista enlazada o encadenada es una colección de elementos ó nodos, en donde cada uno contiene datos y un enlace o liga.

Un nodo es una secuencia de caracteres en memoria dividida en campos (de cualquier tipo). Un nodo siempre contiene la dirección de memoria del siguiente nodo de información si este existe.

Un apuntador es la dirección de memoria de un nodo

La figura siguiente muestra la estructura de un nodo:

El campo liga, que es de tipo puntero, es el que se usa para establecer la liga con el siguiente nodo de la lista. Si el nodo fuera el último, este campo recibe como valor NIL (vacío).

A continuación se muestra el esquema de una lista:

Las operaciones que podemos realizar sobre una lista enlazada son las siguientes:

Recorrido.

Esta operación consiste en visitar cada uno de los nodos que forman la lista . Para recorrer todos los nodos de la lista, se comienza con el primero, se toma el valor del campo liga para avanzar al segundo nodo, el campo liga de este nodo nos dará la dirección del tercer nodo, y así sucesivamente.

Inserción.

Esta operación consiste en agregar un nuevo nodo a la lista. Para esta operación se pueden considerar tres casos: Insertar un nodo al inicio. Insertar un nodo antes o después de cierto nodo. Insertar un nodo al final.

38

Page 39: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Borrado.

La operación de borrado consiste en quitar un nodo de la lista, redefiniendo las ligas que correspondan. Se pueden presentar cuatro casos:

Eliminar el primer nodo. Eliminar el último nodo. Eliminar un nodo con cierta información. Eliminar el nodo anterior o posterior al nodo cierta con información.

Búsqueda.

Esta operación consiste en visitar cada uno de los nodos, tomando al campo liga como puntero al siguiente nodo a visitar.

3.1.1 Simples.

En esta sección se mostrarán algunos algoritmos sobre listas simples sin nodo de cabecera y con nodo de cabecera.

Una lista con nodo de cabecera es aquella en la que el primer nodo de la lista contendrá en su campo dato algún valor que lo diferencíe de los demás nodos (como : *, -, +, etc). Un ejemplo de lista con nodo de cabecera es el siguiente:

En el caso de utilizar listas con nodo de cabecera, usaremos el apuntador CAB para hacer referencia a la cabeza de la lista.

Para el caso de las listas sin nodo de cabecera, se usará la expresión TOP para referenciar al primer nodo de la lista, y TOP(dato), TOP(liga) para hacer referencia al dato almacenado y a la liga al siguiente nodo respectivamente.

Algoritmo de Creación

top<--NILrepite         new(p)         leer(p(dato))          si top=NIL entonces        top<--p          en caso contrario        q(liga)<--p           p(liga)<--NIL           q<--p           mensaje('otro nodo?')            leer(respuesta)hasta respuesta=no 

39

Page 40: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Algoritmo para Recorrido

p<--topmientras p<>NIL haz        escribe(p(dato))        p<--p(liga:)  Algoritmo para insertar al final

p<--topmientras p(liga)<>NIL haz        p<--p(liga)new(q)p(liga)<--qq(liga)<--NIL  Algoritmo para insertar antes/después de 'X' información

p<--topmensaje(antes/despues)lee(respuesta)si antes entonces        mientras p<>NIL haz                si p(dato)='x' entonces                        new(q)                        leer(q(dato))                        q(liga)<--p                        si p=top entonces                                top<--q                        en caso contrario                                r(liga)<--q                        p<--nil                en caso contrario                        r<--p                        p<--p(link)si despues entonces        p<--top        mientras p<>NIL haz                si p(dato)='x' entonces                        new(q)                        leer(q(dato))                        q(liga)<--p(liga)                        p(liga)<--q                        p<--NIL                en caso contrario                        p<--p(liga)        p<--top        mientras p(liga)<>NIL haz                p<--p(liga)        new(q)        p(liga)<--q        q(liga)<--NIL

40

Page 41: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

  Algoritmo para borrar un nodo

p<--topleer(valor_a_borrar)mientras p<>NIL haz        si p(dato)=valor_a_borrar entonces                si p=top entonces                        si p(liga)=NIL entonces                                top<--NIL                        en caso contrario                                top(liga)<--top(liga)                en caso contrario                        q(liga)<--p(liga)                dispose(p)                p<--NIL        en caso contrario                q<--p                p<--p(liga)  Algoritmo de creación de una lista con nodo de cabecera

new(cab)cab(dato)<--'*'cab(liga)<--NILq<--cabrepite          new(p)          leer(p(dato))          p(liga)<--NIL          q<--p          mensaje(otro nodo?)           leer(respuesta)hasta respuesta=no  Algoritmo de extracción en una lista con nodo de cabecera

leer(valor_a_borrar)p<--cabq<--cab(liga)mientras q<>NIL haz        si q(dato)=valor_a_borrar entonces                p<--q(liga)                dispose(q)                q<--NIL        en caso contrario                p<--q                q<--q(liga)

3.1.2 Dobles.

41

Page 42: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Una lista doble , ó doblemente ligada es una colección de nodos en la cual cada nodo tiene dos punteros, uno de ellos apuntando a su predecesor (li) y otro a su sucesor(ld). Por medio de estos punteros se podrá avanzar o retroceder a través de la lista, según se tomen las direcciones de uno u otro puntero.

La estructura de un nodo en una lista doble es la siguiente:

Existen dos tipos de listas doblemente ligadas:

Listas dobles lineales. En este tipo de lista doble, tanto el puntero izquierdo del primer nodo como el derecho del último nodo apuntan a NIL.

Listas dobles circulares. En este tipo de lista doble, el puntero izquierdo del primer nodo apunta al último nodo de la lista, y el puntero derecho del último nodo apunta al primer nodo de la lista.

Debido a que las listas dobles circulares son más eficientes, los algoritmos que en esta sección se traten serán sobre listas dobles circulares.

En la figura siguiente se muestra un ejemplo de una lista doblemente ligada lineal que almacena números:

En la figura siguiente se muestra un ejemplo de una lista doblemente ligada circular que almacena números:

A continuación mostraremos algunos algoritmos sobre listas enlazadas. Como ya se mencionó, llamaremos li al puntero izquierdo y ld al puntero derecho, también usaremos el apuntador top para hacer referencia al primer nodo en la lista, y p para referenciar al nodo presente.

42

Page 43: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Algoritmo de creación

top<--NILrepite si top=NIL entonces

new(p)lee(p(dato))p(ld)<--pp(li)<--ptop<--p

en caso contrarionew(p)lee(p(dato))p(ld)<--topp(li)<--pp(ld(li))<--p

mensaje(otro nodo?) lee (respuesta)hasta respuesta=no

Algoritmo para recorrer la lista

--RECORRIDO A LA DERECHA.

p<--toprepite escribe(p(dato)) p<--p(ld)hasta p=top

--RECORRIDO A LA IZQUIERDA.

p<--toprepite escribe(p(dato)) p<--p(li)hasta p=top(li)

Algoritmo para insertar antes de 'X' información

43

Page 44: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

p<--topmensaje (antes de ?)lee(x)repite si p(dato)=x entonces

new(q)leer(q(dato))si p=top entonces

top<--qq(ld)<--pq(li)<--p(li)p(ld(li))<--qp(li)<--qp<--top

en caso contrariop<--p(ld)

hasta p=top

Algoritmo para insertar despues de 'X' información

p<--topmensaje(despues de ?)lee(x)repite si p(dato)=x entonces

new(q)lee(q(dato))q(ld)<--p(ld)q(li)<--pp(li(ld))<--qp(ld)<--qp<--top

en caso contrariop<--p(ld)

hasta p=top

Algoritmo para borrar un nodo

p<--topmensaje(Valor a borrar)lee(valor_a_borrar)repite si p(dato)=valor_a_borrar entonces

p(ld(li))<--p(ld)p(li(ld))<--p(li)si p=top entonces

si p(ld)=p(li) entoncestop<--nil

en caso contrariotop<--top(ld)

dispose(p)p<--top

en caso contrariop<--p(ld)

hasta p=top

3.1.3 Circulares.

44

Page 45: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Las listas circulares tienen la característica de que el último elemento de la misma apunta al primero

La siguiente figura es una representación gráfica de una lista circular.

Enseguida se mostrarán los algoritmos más comunes en listas circulares. Al igual que en las secciones anteriores, utilizaremos el apuntador top para hacer referencia al primer nodo en la lista.

Algoritmo de creación

repite      new(p)      lee(p(dato))       si top=nil entonces        top<--p        q<--p      en caso contrario        q(liga)<--p        q<--p     p(liga)<--top     mensaje (otro nodo ?)     lee(respuesta)hasta respuesta=no  Algoritmo para recorrer la lista

p<--toprepite      escribe(p(dato))       p<--p(liga)hasta p=top

45

Page 46: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Algoritmo para insertar antes de 'X' información

new(p)lee(p(dato))si top=nil entonces       top<--p       p(liga)<--topen caso contrario       mensaje(antes de ?)       lee(x)       q<--top        r<--top(liga)        repite        si q(dato)=x entonces                p(liga)<--q                r(liga)<--p                si p(liga)=top entonces                        top<--p        q<--q(liga)        r<--r(liga)      hasta q=top 

Algoritmo para insertar después de 'X' información

new(p)lee(p(dato))mensaje(después de ?)lee(x)q<--topr<--top(liga)repite      si q(dato)=x entonces        q(liga)<--p        p(liga)<--r      q<--q(liga)      r<--r(liga)hasta q=top

46

Page 47: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Algoritmo para borrar mensaje(valor a borrar )lee(valor_a_borrar)q<--topr<--topp<--topmientras q(liga)<>top haz        q<--q(liga)repite      si p(dato)=valor_a_borrar entonces        si p=top entonces                si top(liga)=top entonces                        top<--NIL                en caso contrario                        top<--top(liga)                        q(liga)<--top        en caso contrario                r(liga)<--p(liga)        dispose(p)        p<--top      en caso contrario        r<--p        p<--p(liga)hasta p=top

3.1.4 Multilistas.

Este método de búsqueda permite accesar la información de manera ordenada a través de campos claves. Las multilistas permiten llegar a un registro por diferentes caminos. El camino lo determina el campo clave sobre el cual se haga la búsqueda. A continuación se presenta un ejemplo de multilistas.

Supóngase que se tiene un archivo en el cual cada registro almacena la siguiente información:

Nombre Profesión Categoría

Se tienen los datos de seis personas:

Juan Matemático 1Daniel Físico 2José Matemático 2Pascual Ingeniero 3Miguel Ingeniero 1Felipe Abogado 2

47

Page 48: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

En este caso, la información de cada individuo puede accesarse por medio de su profesión y por medio de su categoría, que son los atributos que permiten realizar búsqueda directa en el archivo. Como puede verse en la figura siguiente, se tiene una lista por profesión y una por categoría.

En general las multilistas son recomendables cuando la búsqueda se hace sobre un solo atributo. En caso de necesitarse una combinación de atributos es preferible usar listas invertidas.

3.1.5 Clases para la implementación de listas.

Declaración de listas enlazadas

En C++, los nodos de una lista enlazada se representan mediante registros de dos campos: un campo para los datos y otro para el enlace con el siguiente nodo.

Ejemplo Las declaraciones para una lista enlazada de nombres son las siguientes:

TYPE

TipoElementosLista = ARRAY[1..5] OF char; PteroLista = ^NodoLista; NodoLista = RECORD Datos : TipoElementosLista; Sig : PteroLista END; TipoListaEnlazada = PteroLista;

VAR

Lista : TipoListaEnlazada;

En este ejemplo, la variable Lista será un puntero al primer nodo de una lista o la constante puntero NIL. Nótese, además, que la definición del tipo puntero PteroLista precede a la definición del tipo registro NodoLista. Esta es la única situación en la que se permite utilizar un identificador (en este caso, NodoLista) antes de definirlo.

Crear una lista enlazada vacía

Para construir una lista enlazada debemos ser capaces de crear una lista vacía.

PROCEDURE CrearLista( VAR Lista : TipoListaEnlazada );BEGIN Lista := NIL;END

48

Page 49: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Comprobar si una lista enlazada está vacía

Dado que una lista enlazada vacía se representa mediante un puntero nulo, resulta sencillo determinar si una lista enlazada está vacía o no.

FUNCTION ListaVacia( Lista : TipoListaEnlazad ) : boolean;BEGIN ListaVacia := Lista = NILEND

Añadir un elemento al principio de una lista enlazada

Uno de los métodos para construir una lista enlazada consiste en añadir repetidamente elementos al principio de la lista, comenzando con una lista vacía.

PROCEDURE AnnadirPrincLista( VAR Lista : TipoListaEnlazada; Elem : TipoElementosLista );VAR PteroTemp : PteroLista;

BEGIN new( PteroTemp ); PteroTerm^.Datos := Elem; PteroTemp^.Sig := Lista; Lista := PteroTermEND

Recorrer una lista enlazada

Una vez que se ha construido una lista enlazada podemos querer recorrerla desde el principio hasta el final, realizando algún tipo de procesamiento sobre cada uno de los elementos (por ejemplo, visualizarlo).

Para movernos por una lista enlazada, la idea es variar una variable puntero dentro de una estructura de repetición, utilizando los campos de enlaces para saltar de un nodo al siguiente.

Ejemplo El siguiente procedimiento permite visualizar los valores de una lista.

PROCEDURE VisualizarEnlazada( Lista : TipoListaEnlaza );VAR PteroAct : PteroLista;

BEGIN PteroAct := Lista; WHILE PteroAct <> NIL DO BEGIN write( PteroAct^.Datos ); PteroAct := PteroAct^.Sig END END

49

Page 50: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

UNIDAD 4 ESTRUCTURAS NO LINEALES

4.1 Árboles.

A los árboles ordenados de grado dos se les conocen como árboles binarios ya que cada nodo del árbol no tendrá más de dos descendientes directos. Las aplicaciones de los árboles binarios son muy variadas ya que se les puede utilizar para representar una estructura en la cual es posible tomar decisiones con dos opciones en distintos puntos.

La representación gráfica de un árbol binario es la siguiente:

4.1.1 Definición.

En ciencias de la computación, un árbol es una estructura de datos ampliamente usada que emula la forma de un árbol (un conjunto de nodos conectados). Un nodo es la unidad sobre la que se construye el árbol y puede tener cero o más nodos hijos conectados a él. Se dice que un nodo a es padre de un nodo b si existe un enlace desde a hasta b (en ese caso, también decimos que b es hijo de a). Sólo puede haber un único nodo sin padres, que llamaremos raíz. Un nodo que no tiene hijos se conoce como hoja.

Formalmente, podemos definir un árbol de la siguiente forma recursiva:

Caso base: un árbol con sólo un nodo (es a la vez raíz del árbol y hoja).

Un nuevo árbol a partir de un nodo nr y k árboles de raíces con elementos cada uno, puede construirse estableciendo una relación padre-hijo entre nr y cada una de las raíces de los k árboles. El árbol resultante de nodos tiene como raíz el nodo nr, los nodos son los hijos de nr y el conjunto de nodos hoja está formado por la unión de los k conjuntos hojas iniciales. A cada uno de los árboles Ai se les denota ahora subárboles de la raíz.

Una sucesión de nodos del árbol, de forma que entre cada dos nodos consecutivos de la sucesión haya una relación de parentesco, decimos que es un recorrido árbol.

50

Page 51: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

Existen dos recorridos típicos para listar los nodos de un árbol: primero en profundidad y primero en anchura. En el primer caso, se listan los nodos expandiendo el hijo actual de cada nodo hasta llegar a una hoja, donde se vuelve al nodo anterior probando por el siguiente hijo y así sucesivamente. En el segundo, por su parte, antes de listar los nodos de nivel n + 1 (a distancia n + 1 aristas de la raíz), se deben haber listado todos los de nivel n. Otros recorridos típicos del árbol son preorden, postorden e inorden:

El recorrido en preorden, también llamado orden previo consiste en recorrer en primer lugar la raíz y luego cada uno de los hijos en orden previo.

El recorrido en inorden, también llamado orden simétrico (aunque este nombre sólo cobra significado en los árboles binarios) consiste en recorrer en primer lugar A1, luego la raíz y luego cada uno de los hijos en orden simétrico.

El recorrido en postorden, también llamado orden posterior consiste en recorrer en primer cada uno de los hijos en orden posterior y por último la raíz.

4.1.2 Representación en memoria de árboles.

Hay dos formas tradicionales de representar un árbol binario en memoria:

Por medio de datos tipo punteros también conocidos como variables dinámicas o listas.

Por medio de arreglos.

Sin embargo la más utilizada es la primera, puesto que es la más natural para tratar este tipo de estructuras.

Los nodos del árbol binario serán representados como registros que contendrán como mínimo tres campos. En un campo se almacenará la información del nodo. Los dos restantes se utilizarán para apuntar al subárbol izquierdo y derecho del subárbol en cuestión.

Cada nodo se representa gráficamente de la siguiente manera:

51

Page 52: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

El algoritmo de creación de un árbol binario es el siguiente:

Procedimiento crear(q:nodo) inicio

mensaje("Rama izquierda?")lee(respuesta)si respuesta = "si" entonces

new(p)q(li) <-- nilcrear(p)

en caso contrarioq(li) <-- nil

mensaje("Rama derecha?")lee(respuesta)si respuesta="si" entonces

new(p)q(ld)<--pcrear(p)

en caso contrarioq(ld) <--nil

finINICIO

new(p)raiz<--pcrear(p)

FIN

4.1.2.1 Árboles generales.

Los árboles representan las estructuras no lineales y dinámicas de datos más importantes en computación. Dinámicas porque las estructuras de árbol pueden cambiar durante la ejecución de un programa. No lineales, puesto que a cada elemento del árbol pueden seguirle varios elementos.

Los árboles pueden ser construidos con estructuras estáticas y dinámicas. Las estáticas son arreglos, registros y conjuntos, mientras que las dinámicas están representadas por listas.

La definición de árbol es la siguiente: es una estructura jerárquica aplicada sobre una colección de elementos u objetos llamados nodos; uno de los cuales es conocido como raíz. Además se crea una relación o parentesco entre los nodos dando lugar a términos como padre, hijo, hermano, antecesor, sucesor, ancestro, etc.. Formalmente se define un árbol de tipo T como una estructura homogénea que es la concatenación de un elemento de tipo T junto con un número finito de árboles disjuntos, llamados subárboles. Una forma particular de árbol puede ser la estructura vacía.

52

Page 53: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

La figura siguiente representa a un árbol general.

Se utiliza la recursión para definir un árbol porque representa la forma más apropiada y porque además es una característica inherente de los mismos.

Los árboles tienen una gran variedad de aplicaciones. Por ejemplo, se pueden utilizar para representar fórmulas matemáticas, para organizar adecuadamente la información, para construir un árbol genealógico, para el análisis de circuitos eléctricos y para numerar los capítulos y secciones de un libro.

4.1.2.2 Árboles binarios.

Existen cuatro tipos de árbol binario:.

A. B. Distinto. A. B. Similares. A. B. Equivalentes. A. B. Completos.

A continuación se hará una breve descripción de los diferentes tipos de árbol binario así como un ejemplo de cada uno de ellos.

A. B. DISTINTO

Se dice que dos árboles binarios son distintos cuando sus estructuras son diferentes. Ejemplo:

53

Page 54: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

A. B. SIMILARES

Dos árboles binarios son similares cuando sus estructuras son idénticas, pero la información que contienen sus nodos es diferente. Ejemplo:

A. B. EQUIVALENTES

Son aquellos árboles que son similares y que además los nodos contienen la misma información. Ejemplo:

A. B. COMPLETOS

Son aquellos árboles en los que todos sus nodos excepto los del ultimo nivel, tiene dos hijos; el subárbol izquierdo y el subárbol derecho.

4.1.3 Recorridos en un árbol binario.

Hay tres maneras de recorrer un árbol: en inorden, preorden y postorden. Cada una de ellas tiene una secuencia distinta para analizar el árbol.

4.1.3.1 Preorden.

PREORDEN

Examinar la raíz. Recorrer el subárbol izquierdo en preorden. recorrer el subárbol derecho en preorden.

54

Page 55: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

4.1.3.2 Inorden.

INORDEN

Recorrer el subárbol izquierdo en inorden. Examinar la raíz. Recorrer el subárbol derecho en inorden.

4.1.3.3 Posorden.

POSTORDEN

Recorrer el subárbol izquierdo en postorden. Recorrer el subárbol derecho en postorden. Examinar la raíz.

4.1.4 Balanceo de árboles binarios.

Mantener un árbol perfectamente balanceado es muy costoso, entonces se adopta un concepto menos estricto de balanceo: árboles balanceados (equilibrados).

Un árbol está balanceado si para cada uno de sus nodos se tiene que las alturas de sus dos subárboles difieren a lo más en 1.

Se tiene que un árbol perfectamente balanceado es también balanceado; pero no es cierto lo contrario.

Para estos árboles el mantenimiento del balanceo no es muy costoso, y las operaciones de búsqueda, inserción y borrado mantienen su orden O(log2n).Los árboles pueden estar balanceados por altura o por peso.

• Arbol balanceado por altura: en dónde todos los hijos o nodos hoja se intentan mantener a la misma distancia de la raíz.

• Arbol balanceado por peso: en dónde los nodos más visitados o utilizados se mantienen a poca distancia de la raíz Un árbol es un grafo conexo y sin ciclos.

Propiedades:

Si G = (V,A) es un árbol de n vértices, entonces:

1) Para todo par de vértices x e y existe un único camino de x a y.

55

Page 56: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

2) Todas las aristas de G son puentes.

3) ½ A½ = n - 1.

4) Todo árbol tiene al menos dos hojas (vértices de grado uno). Caracterizaciones: Un grafo G=(V,A) es un árbol Û Para todo par de vértices x e y existe un único camino de x a y Û G es conexo y todas las aristas son puentes Û G es acíclico y maximal (la adición de una arista nueva origina un ciclo) Û G es conexo y ½ A½ = n - 1 Û G es acíclico y ½ A½ = n - 1 Los árboles forman una de las subclases de las gráficas de uso más amplio. En el terreno de la computación los árboles sirven para organizar y relacionar los datos de una base de datos.

4.1.5 Clases para la implementación de árboles.

Este tipo de estructura es usual incluso fuera del campo de la informática. El lector seguramente conoce casos como los árboles gramaticales para analizar oraciones, los árboles genealógicos ,representación de jerarquías, etc...La estructuración en árbol de los elementos es fundamental dentro del campo de la informática aplicándose en una amplia variedad de problemas como veremos más adelante.

En principio podemos considerar la estructura de árbol de manera intuitiva como una estructura jerárquica. Por tanto, para estructurar un conjunto de elementos ei en árbol, deberemos escoger uno de ellos e1 al que llamaremos raíz del árbol. Del resto de los elementos se selecciona un subconjunto e2,...,ek estableciendo una relación padre-hijo entre la raíz y cada uno de dichos elementos de manera que e1 es llamado el padre de e2,de e3,...ek y cada uno de ellos es llamado un hijo de e1. Iterativamente podemos realizar la misma operación para cada uno de estos elementos asignando a cada uno de ellos un número de 0 o más hijos hasta que no tengamos más elementos que insertar. El único elemento que no tiene padre es e1,la raíz del árbol. Por otro lado hay un conjunto de elementos que no tienen hijos aunque sí padre que son llamados hojas .Como hemos visto la relación de paternidad es una relación uno a muchos.

Para tratar esta estructura cambiaremos la notación:

Las listas tienen posiciones. Los árboles tienen nodos.

Las listas tienen un elemento en cada posición. Los árboles tienen una etiqueta en cada nodo (algunos autores distinguen entre árboles con y sin etiquetas. Un árbol sin etiquetas tiene sentido aunque en la inmensa mayoría de los problemas necesitaremos etiquetar los nodos. Es por ello por lo que a partir de ahora sólo haremos referencia a árboles etiquetados).

56

Page 57: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

4.2 Grafos

Hoy en día podemos ver muchas cosas que nos pueden parecer de lo mas cotidianas, carreteras, líneas telefónicas, líneas de televisión por cable, el transporte colectivo metro, circuitos eléctricos de nuestras casas, automóviles, y tantas cosas mas; lo que no pensamos frecuentemente es que estos forman parte de algo que en matemáticas se denomina como grafos.

En este trabajo se tratará de explicar lo que son los grafos, sus tipos, y algunas derivaciones de ellos, así como su representación gráfica y en algunos casos, su representación en algún programa informático, así como en la memoria.

En este trabajo, se explicando de manera muy sencilla los conceptos y algunas metodologías con un lenguaje no tan rebuscado para su mayor entendimiento.

4.2.1 Definición.

Desafortunadamente no existe una terminología estandarizada en la teoría de los grafos, por lo tanto es oportuno aclarar que las presentes definiciones pueden variar ligeramente entre diferentes publicaciones de estructura de datos y de teoría de grafos, pero en general se puede decir que un grafo como indica su nombre lo indica es la representación (para nuestro caso) gráfica de los datos de una situación particular, ejemplo:

Los datos contienen, en algunos casos, relaciones entre ellos que no es necesariamente jerárquica. Por ejemplo, supongamos que unas líneas aéreas realizan vuelos entre las ciudades conectadas por líneas como se ve en la figura anterior (más adelante se presentaran grafos con estructuras de datos); la estructura de datos que refleja esta relación recibe el nombre de grafo.

Se suelen usar muchos nombres al referirnos a los elementos de una estructura de datos. Algunos de ellos son "elemento", "ítem", "asociación de ítems", "registro", "nodo" y "objeto". El nombre que se utiliza depende del tipo de estructura, el contexto en que usamos esa estructura y quien la utiliza.

En la mayoría de los textos de estructura de datos se utiliza el término "registro" al hacer referencia a archivos y "nodo" cuando se usan listas enlazadas, árboles y grafos.

También un grafo es una terna G = (V,A,j ), en donde V y A son conjuntos finitos, y j es una aplicación que hace corresponder a cada elemento de A un par de elementos de V. Los elementos de V y de A se llaman, respectivamente, "vértices" y "aristas" de G, y j asocia entonces a cada arista con sus dos vértices.

Esta definición da lugar a una representación gráfica, en donde cada vértice es un punto del plano, y cada arista es una línea que une a sus dos vértices.

57

Page 58: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

4.2.2 Tipos de grafos.

Podemos clasificar los grafos en dos grupos: dirigidos y no dirigidos. En un grafo no dirigido el par de vértices que representa un arco no está ordenado. Por lo tanto, los pares (v1, v2) y (v2, v1) representan el mismo arco. En un grafo dirigido cada arco está representado por un par ordenado de vértices, de forma que y representan dos arcos diferentes.

Ejemplos

G1 = (V1, A1)V1 = {1, 2, 3, 4} A1 = {(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)}G2 = (V2, A2)V2 = {1, 2, 3, 4, 5, 6} A2 = {(1, 2), (1, 3), (2, 4), (2, 5), (3, 6)}G3 = (V3, A3)V3 = {1, 2, 3} A3 = { <1, 2>, <2, 1>, <2, 3> }

Gráficamente estas tres estructuras de vértices y arcos se pueden representar de la siguiente manera:

Algunos de los principales tipos de grafos son los que se muestran a continuación:

Grafo regular: Aquel con el mismo grado en todos los vértices. Si ese grado es k lo llamaremos k-regular.

Por ejemplo, el primero de los siguientes grafos es 3-regular, el segundo es 2-regular y el tercero no es regular

Grafo bipartito: Es aquel con cuyos vértices pueden formarse dos conjuntos disjuntos de modo que no haya adyacencias entre vértices pertenecientes al mismo conjunto Ejemplo.- de los dos grafos siguientes el primero es bipartito y el segundo no lo es.

Grafo completo: Aquel con una arista entre cada par de vértices. Un grafo completo con n vértices se denota Kn.

A continuación pueden verse los dibujos de K3, K4, K5 y K6

Un grafo bipartito regular: se denota Km,n donde m, n es el grado de cada conjunto disjunto de vértices.

58

Page 59: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

A continuación ponemos los dibujos de K1,2, K3,3, y K2,5

Grafo nulo: Se dice que un grafo es nulo cuando los vértices que lo componen no están conectados, esto es, que son vértices aislados.

Grafos Isomorfos: Dos grafos son isomorfos cuando existe una correspondencia biunívoca (uno a uno), entre sus vértices de tal forma que dos de estos quedan unidos por una arista en común.

Grafos Platónicos: Son los Grafos formados por los vértices y aristas de los cinco sólidos regulares (Sólidos Platónicos), a saber, el tetraedro, el cubo, el octaedro, el dodecaedro y el icosaedro.

59

Page 60: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

GRAFOS EULERIANOS.

Para definir un camino euleriano es importante definir un camino euleriano primero. Un camino euleriano se define de la manera más sencilla como un camino que contiene todos los arcos del grafo.

Teniendo esto definido podemos hablar de los grafos eulerianos describiéndolos simplemente como aquel grafo que contiene un camino euleriano. Como ejemplos tenemos las siguientes imágenes:

El primer grafo de ellos no contiene caminos eulerianos mientras el segundo contiene al menos uno.

GRAFOS CONEXOS.

Un grafo se puede definir como conexo si cualquier vértice V pertenece al conjunto de vértices y es alcanzable por algún otro. Otra definición que dejaría esto más claro sería: “un grafo conexo es un grafo no dirigido de modo que para cualquier par de nodos existe al menos un camino que los une”.

4.2.3 Representación de grafos en memoria.

Los grafos se representan en memoria secuencial mediante matrices de adyacencia.

Una matriz de adyacencia, es una matriz de dimensión n*n, en donde n es el número de vértices que almacena valores booleanos, donde matriz M[i,j] es verdadero si y solo si existe un arco que vaya del vértice y al vértice j.Veamos el siguiente grafo dirigido:

60

Page 61: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

La matriz de adyacencia, que se obtuvo a partir del grafo anterior es la siguiente:

Los grafos se representan en memoria enlazada mediante listas de adyacencia.

Una lista de adyacencia, se define de la siguiente manera: Para un vértice i es una lista en cierto orden formada por todos los vértices adyacentes [a,i]. Se puede representar un grafo por medio de un arreglo donde cabeza de i es un apuntador a la lista de adyacencia al vértice i.

Veamos el siguiente grafo dirigido:

La lista de adyacencia, que se obtuvo a partir del grafo anterior es la siguiente:

4.2.4 Clases para la implementación de grafos.

En esta sección analizaremos algunas de las operaciones sobre grafos, como:  

Creación. Inserción. Búsqueda. Eliminación.

61

Page 62: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

En esta sección, continuaremos utilizando los apuntadores que se usaron en las secciones anteriores. TOP para hacer referencia al primer nodo, LD para indicar liga derecha y LA para indicar liga abajo, por último usaremos los apuntadores P y Q para hacer referencia a los nuevos nodos que vayan a ser usados.

ALGORITMO DE CREACION.

repite      si top=NIL entonces        new(top)        top(la)<--NIL        top(ld)<--NIL        lee(top(dato))        q<--top      en caso contrario        new(p)        p(ld)<--NIL        p(la)<--NIL        q(la)<--p        lee(p(dato))        q<--p      mensaje(otro vertice ?)       lee(respuesta)hasta repuesta=nop<--topmientras p<>NIL haz        mensaje(tiene vértices adyacentes p(dato) ?)        lee(respuesta)        si respueta=si entonces                repite                      new(q)                      lee(q(dato))                      q(ld)<--p(ld)                      p(ld)<--q                      mensaje(otro vértice ?)                      lee(respuesta2)                hasta respuesta2=no        p<--p(la)

ALGORITMO DE INSERCION

mensaje(valor a insertar ?)lee(valor_a_insertar)si top<>NIL entonces        p<--top        mientras p(la)<>NIL haz                p<--p(la)        new(q)

62

Page 63: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

        lee(q(dato))        p(la)<--q        q(la)<--NIL        mensaje(Hay vértices adyacentes?)        lee(respuesta)        si respuesta=si entonces                mensaje(Cuantos vértices?)                lee(número_vértices)                desde i=1 hasta número_vértices haz                        new(p)                        lee(p(dato))                        q(ld)<--p                        q<--q(ld)en caso contrario        mensaje(no existe lista)ALGORITMO DE BUSQUEDAmensaje(vértice a buscar)lee(vértice_a_buscar)p<--toprepite      si p(dato)=vértice_a_buscar entonces        repite              p<--p(ld)              escribe(p(dato))        hasta p(ld)=NIL      en caso contrario        p<--(la)hasta p=NIL

ALGORITMO DE BORRADO

mensaje(vértice a borrar ?)lee(vértice_a_borrar)p&Lt--topr<--pq<--psw<--falsorepite      si p(dato)=vértice_a_borrar entonces        si p=top entonces                top<--top(la)                r<--top                sw<--verdadero        en caso contrario                r(la)<--p(la)        repite             p<--p(ld)             dispose(q)             q<--p

63

Page 64: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

        hasta p=NIL        si sw=verdadero entonces                p<--r                q<--p        en caso contrario                p<--r(la)                q<--p      en caso contrario        r<--p        repite              q<--p(ld)              si q(dato)=vértice_a_borrar entonces                p(ld)<--q(ld)                dispose(q)                q<--p             en caso contrario                p<--p(ld)hasta p=NIL

64

Page 65: Tecnológico de Estudios Superiores de Ecatepec · Web viewEn caso de necesitarse una combinación de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementación

BIBLIOGRAFIAS

Aho, A.V., J.E. Hopcroft, J.D. Ullman, Estructuras de datos y algoritmos, Addison-Wesley, 1988.

Arnold, K., J. Gosling, D. Holmes, El Lenguaje de Programación Java, 3ª Ed., Addison-Wesley, 2001.

Arnow, D., G. Weiss, Introducción a la Programación con Java. Un enfoque Orientado a Objetos, Addison-Wesley, 2000.

Eckel, B., Piensa en Java. 2ª Edición, Prentice-Hall, 2002.

Horowitz, E., S. Sahni, Fundamentals of Data Structures in Pascal, Computer Science, 1994.

Joyanes, L., I. Zahonero, Estructuras de Datos. Algoritmos, abstracción y objetos, McGraw-Hill, 1998.

Peña, Ricardo, Diseño de programas. Formalismo y abstracción, Prentice-Hall, 1998.

Weiss, M.A., Estructuras de datos y algoritmos, Addison-Wesley, 1995.

Wirth, N., Algoritmos y Estructuras de Datos, Prentice-Hall Iberoamericana, 1987.

65