Manual Estructura de Datos
Manual Estructura de Datos
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 prctica los conceptos adquiridos mediante resolucin de problemas. TEMARIO 1.- TIPOS DE DATOS 1.1 Tipos de datos. 2
1.1.1 Tipos de datos simples. 1.1.1.1 Definicin de bit, byte, carcter y palabra. 1.1.1.2 Manipulacin de bits. 1.1.1.3 Representacin de datos simples. 1.1.2 Tipos de datos abstractos. 1.2 Estructuras de datos. 1.2.1 Definicin. 1.2.2 Clasificacin. 1.2.2.1 Lineales y no lineales. 1.2.2.2 Dinmicas y estticas. 2.- ESTRUCTURAS LINEALES 2.1 Arreglos. 2.1.1 Definicin. 2.1.2 Unidimensionales. 2.1.3 Bidimensionales. 2.1.4 Multidimensionales. 2.1.5 Resolucin de problemas con arreglos. 2.1.6 Clases para la implementacin de arreglos. 2.2 Pilas. 2.2.1 Definicin. 2.2.2 Operaciones. 2.2.3 Clases para la implementacin de pilas. 2.3 Colas. 2.3.1 Definicin. 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 implementacin de colas.
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 implementacin de listas. 4.- ESTRUCTURAS NO LINEALES
4.1 rboles. 4.1.1 Definicin. 4.1.2 Representacin 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 implementacin de rboles. 4.2 Grafos. 4.2.1 Definicin. 4.2.2 Tipos de grafos. 4.2.3 Representacin de grafos en memoria. 4.2.4 Clases para la implementacin de grafos.
UNIDAD1 TIPOS DE DATOS 1.1 Tipos de datos. El manejo de la informacin en cualquier lenguaje de programacin se realiza mediante diferentes clases de datos.
Entero (Integer)
Carcter (Char) Caracteres del cdigo ASCII Boleano Pueden contener los valores de falso o verdadero (Boolean) Real Nmeros que pueden incluir una parte decimal En una secuencia de caracteres que se trata como un solo Cadena (String) dato.
Un programa debe ser capaz de manejar diferentes tipos de datos, como pueden ser nmeros enteros, reales, caracteres, cadenas de caracteres, etc. Para lograr el manejo de toda esta informacin. Algunos de los ms importantes se citan en seguida: Tipos enteros En esta categora generalmente cuenta con 5 tipos diferentes, cada uno abarca un rango especfico 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 presicin. 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 nmero en formato hexadecimal, para hacer esto solo se le antepone el smbolo "$" al valor hexadecimal, al momento de visualizar dicho valor, o utilizarlo en alguna operacin ser como decimal casi siempre en todos los casos que se utilice. Tipos reales Los nmeros reales son aquellos que cuentan con una parte decimal. En algunos lenguajes de programacin se tienen varios tipos de datos reales, pero no se puede utilizar, ms que el tipo real, en mquinas que no cuenten con un coprocesador matemtico. Los tipos de datos reales son:
Los nmeros reales deben llevar por fuerza al menos un dgito de cada lado del punto decimal as sea ste un cero. Como ejemplo, el nmero 5 debe representarse como: 5.0, el .5 como 0.5 , etc. En este tipo de datos se utiliza la notacin cientfica, que es igual a la de las calculadoras, el dgito que se encuentra a continuacin de la E representa la potencia a la que se elevar el nmero 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 carcter Los caracteres son cada uno de los smbolos que forman el cdigo ASCII.. Los caracteres se especifican entre apostrofes: 'a' </TD 'B' </TD '2' '#' El tipo Char es un tipo ordinal en algunos lenguajes de programacin, esto quiere decir que sus elementos vlidos siguen una secuencia ordenada de valores individuales. La secuencia de caracteres para este tipo corresponde al nmero del cdigo ASCII, del 0 al 255.
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 carcter.
Tipo cadena
Las cadenas son secuencias de caracteres o arreglos que tienen una longitud mxima de 255 caracteres. Se definen entre apostrofes.
La cadena 'Ernesto Chvez' es almacenada en la variable nombre definida como tipo cadena. El tamao por defecto para un tipo string es de 255 caracteres, pero es posible definir uno mas pequeo utilizando el siguiente formato: Variable : Cadena[Tamao]; Donde Variable es la variable a definir y Tamao es el nmero mximo de caracteres que podr contener esa variable (naturalmente mayor a 0 y menor a 256). Es posible acceder a un solo carcter de una cadena utilizando inmediatamente despus del nombre de la misma la posicin del carcter encerrada entre corchetes. Por ejemplo:
Nombre : String[30]; {Permite un mximo de 30 caracteres en la variable} Nombre := 'Ernesto Chvez'; Escribir (Nombre[5]); {Visualiza el 5to carcter de la cadena} Tipos lgicos 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 ingls: True y el falso por False; tambin se representan por 1 y por 0 respectivamente. El tipo est definido como Boolean.
Los datos lgicos tienen una enorme aplicacin en la evaluacin 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 caracterstica 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, carcter, boleanos, enumerados y subrrango (los dos ltimos no existen en algunos lenguajes de programacin). 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 bsicos de cualquier dato estructurado son datos simples.
Todas las estructuras de datos constituyen un aspecto muy importante en la computacin, estas son: Arreglos. Registros. conjuntos. Definicin de bit, byte, carcter y palabra.
1.1.1.1
Bit: es una sntesis de dos trminos en ingls: Binary digit, que en espaol significan dgito binario, o lo que es lo mismo, nmero (dgito) con dos posibles valores (binario). El trmino surge de usar las dos primeras letras de Binary con la ltima de digit.: bit. Es la unidad de informacin ms sencilla posible en el sistema binario.
Byte: Unidad de informacin que consta de 8 bits equivalente a un nico carcter, como una letra, nmero o signo de puntuacin. Carcter: Es un elemento tomado de un conjunto de smbolos. Un ejemplo de un conjunto de smbolos es {0,1,2,3,4,5,6,7,8,9,A,B,C....Y,z,,-,+,*} en el cual se incluyen dgitos, 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 Manipulacin de bits. Ahora el ser humano digitaliza su entorno. Pero, qu significa digitalizar? Digitalizar es traducir informacin como textos, imgenes o sonidos, a un formato que puedan entender los microprocesadores, y stos slo estn 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 slo acepta dos valores (0 y 1). Tal sencillez tiene su razn de ser: los microprocesadores son circuitos electrnicos plasmados en un material llamado silicio (algo parecido al vidrio) que procesan diminutos impulsos elctricos, el ms pequeo de los cuales es conocido por el nombre de bit. Como impulso elctrico, el microprocesador slo puede detectar cuando un bit tiene carga elctrica --su valor sera, en este caso, 1-- o cuando no la tienen --su valor sera 0 - En este ejemplo manejamos los valores unos y ceros de manera un tanto arbitraria, ya que la presencia o ausencia de carga elctrica 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 lgico, que como vimos se reduce a manejar dos posibles valores, sino de la velocidad con la que se aplica dicha lgica: los microprocesadores actuales pueden procesar varios millones de bits en un slo segundo. 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 informtica es el byte, que consiste en la agrupacin de ocho bits. Ejemplo de combinaciones posibles por nmero 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 maysculas 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 combinacin de valores: Valor de la letra "e" minscula en bits: 0 1100101 Pero si en cambio se presiona la misma tecla en maysculas, el paquete de bits que se estar mandando al microprocesador sera el siguiente: Valor de la letra "E" mayscula en bits: 0 1000101 Mediante combinaciones de bits y bytes es posible representar una cantidad infinita de cosas: desde bibliotecas completas hasta juegos y pelculas, todo un universo de informacin que puede estar en diversas formas; textos, imgenes y sonidos. Se dice que algunas computadoras tienen aritmtica decimal en lugar de binaria. Cuatro bits proporcionan 16 combinaciones, utilizadas para los 10 dgitos de 0 a 9, con 6 combinaciones sin utilizar. El nmero 1944 se muestra abajo codificado en decimal y en binario, utilizando 16 bits en cada ejemplo: Decimal: 0001 1001 0100 0100 binario: 0000011110011000
1.1.1.3 Representacin de datos simples. Los datos que utilizan los programas se pueden clasificar en base a diferentes criterios. Uno de los ms significativos es aquel que dice que todos los datos que utilizan los programas son simples o compuestos. Un dato simple es indivisible (atmico), es decir, no se puede descomponer.
10
Un ao se expresa con un nmero 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 (da, mes, ao). Fecha: Da...: 30 Mes...: 11 Ao...: 2006 Ejemplo 3: Otro ejemplo de dato simple es una letra. Letra...: t
Una letra se representa con un carcter 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)
Clasificacin de los tipos de datos simples Los tipos de datos simples se clasifican en predefinidos y definidos por el programador. La clasificacin completa es:
11
Los tipos de datos simples predefinidos (estndares) son aquellos proporcionados por los lenguajes de programacin. Pero, el programador tambin puede definir sus propios tipos de datos simples (subrangos y enumerados), los cuales se estudiarn ms 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 nmeros enteros, tiene como predecesor al 4, y como sucesor al 6. Sin embargo, entre dos nmeros reales siempre hay un nmero infinito de nmeros. 1.1.2 Tipos de datos abstractos. Un tipo de dato abstracto o TDA (tambin Tipo abstracto de datos o TAD) es un modelo matemtico compuesto por una coleccin de operaciones definidas sobre un conjunto de datos para el modelo.
>
Introduccin
En el mundo de la programacin 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 programacin eran de tipo lineales, ya que un programa
12
se recorra desde un punto marcado como Inicio hasta llegar a un punto Fin. Con el tiempo se fueron creando nuevos lenguajes y en nuestros das los ms utilizados son los llamados Orientados a Objetos. Los Lenguajes Orientados a Objetos (LOO) tienen la caracterstica 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 cmo funcionan los Lenguajes Orientados a Objetos, vamos a introducir un concepto fundamental en las Estructuras de Datos denominado Abstraccin de Datos y que es parte importante de estos Lenguajes y de la manera en que funciona la mayora del software comercial de nuestros das. 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 Definicin Con mucha frecuencia se utilizan los trminos TDA y Abstraccin 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 Programacin Orientados a Objetos son lenguajes formados por diferentes mtodos o funciones y que son llamados en el orden en que el programa lo requiere, o el usuario lo desea. La abstraccin de datos consiste en ocultar las caractersticas de un objeto y obviarlas, de manera que solamente utilizamos el nombre del objeto en nuestro programa. Esto es similar a una situacin 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 tambin sabe que los perros ladran. De manera que yo abstraigo todas las caractersticas de todos los perros en un solo trmino, al cual llamo perro. A esto se le llama Abstraccin y es un concepto muy til en la programacin, ya que un usuario no necesita mencionar todas las caractersticas 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 trmino 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 Abstraccin de Datos. Vamos a poner un ejemplo real de la programacin. Supongamos que en algn Lenguaje de Programacin Orientado a Objetos un pequeo programa saca el rea de un rectngulo de las dimensiones que un usuario decida. Pensemos tambin que el usuario probablemente quiera saber el rea de varios rectngulos. Sera muy tedioso para el programador definir la multiplicacin de base por altura varias veces en el programa, adems que limitara al usuario a sacar un nmero determinado de reas.
13
Por ello, el programador puede crear una funcin denominada rea, la cual va a ser llamada el nmero de veces que sean necesitadas por el usuario y as el programador se evita mucho trabajo, el programa resulta ms rpido, ms eficiente y de menor longitud. Para lograr esto, se crea el mtodo rea de una manera separada de la interfaz grfica presentada al usuario y se estipula ah la operacin a realizar, devolviendo el valor de la multiplicacin. En el mtodo principal solamente se llama a la funcin rea y el programa hace el resto. Al hecho de guardar todas las caractersticas y habilidades de un objeto por separado se le llama Encapsulamiento y es tambin un concepto importante para entender la estructuracin de datos. Caracterizacin Un TDA est caracterizado por un conjunto de operaciones (funciones) al cual le denominaron usualmente como su interfaz pblica y representan el comportamiento del TDA; mientras que la implementacin 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 pblicas que incluyen las operaciones como la +, -, *, etc. En un TDA no se necesita conocer como actan tales operadores sobre la representacin interna de los tipos definidos, que adems, suele ser una implementacin bastante dependiente de la mquina sobre la que trabaje el compilador. Lo interesante es que los lenguajes actuales nos van a permitir ampliar los TDA predefinidos con otros que sern 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 sern llamados polilticos y aquellos TDA simples, como son los tipos predefinidos donde la informacin no es relacionada mediante ninguna estructura y no admiten ms que un valor en cada momento ser denominados TDA monolticos. Ntese que cuando hablemos de un TDA no haremos ninguna alusin al tipo de los elementos sino tan slo a la forma en que estn dispuestos estos elementos. Slo nos interesa la estructura que soporta la informacin y sus operaciones. Para determinar el comportamiento estructural basta con observar la conducta que seguirn 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
14
el uso del usuario y est constituida tanto por la maquinaria algortmica que implemente la semntica de las operaciones como por los datos que sirvan de enlace entre los elementos del TDA, es decir, informacin interna necesaria para la implementacin que se est haciendo para ese comportamiento del TDA. Resumiendo podemos decir, que tanto la implementacin de las operaciones como los elementos internos del TDA sern privados al acceso externo y ocultos a cualquier otro nivel. Un TDA representa una abstraccin: Se destacan los detalles (normalmente pocos) de la especificacin (el qu). Se ocultan los detalles (casi siempre numerosos) de la implementacin (el cmo).
La abstraccin La abstraccin, una de las herramientas que ms nos ayuda a la hora de solucionar un problema, es un mecanismo fundamental para la comprensin de problemas y fenmenos que poseen una gran cantidad de detalles, su idea principal consiste en manejar un problema, fenmeno, objeto, tema o idea como un concepto general, sin considerar la gran cantidad de detalles que estos puedan tener. El proceso de abstraccin presenta dos aspectos complementarios. 1.- Destacar los aspectos relevantes del objeto. 2.- Ignorar los aspectos irrelevantes del mismo (la irrelevancia depende del nivel de abstraccin, ya que si se pasa a niveles ms concretos, es posible que ciertos aspectos pasen a ser relevantes). De modo general podemos decir que la abstraccin permite establecer un nivel jerrquico en el estudio de los fenmenos, el cual se establece por niveles sucesivos de detalles. Generalmente, se sigue un sentido descendente de detalles, desde los niveles ms generales a los niveles ms concretos. Por ejemplo: los lenguajes de programacin 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. La abstraccin nos brinda la posibilidad de ir definiendo una serie de refinamientos sucesivos a nuestro TDA y entindase bien que cuando decimos refinamientos sucesivos nos estamos refiriendo a la estrategia que se utiliza para descomponer un problema en subproblemas. Conforme evoluciona el diseo de software a cada nivel de mdulos se representa un refinamiento en el nivel de abstraccin. Esto es, incluir detalles que fueron obviados en un nivel superior, en un nivel ms bajo de la jerarqua.
15
Veamos los diferentes tipos de abstraccin que podemos encontrar en un programa: 1. Abstraccin funcional: crear procedimientos y funciones e invocarlos mediante un nombre donde se destaca qu hace la funcin y se ignora cmo lo hace. El usuario slo necesita conocer la especificacin de la abstraccin (el qu) y puede ignorar el resto de los detalles (el cmo). 2. Abstraccin de datos: Tipo de datos: proporcionado por los leguajes de alto nivel. La representacin 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 definicin de valores de datos ms cercanos al problema que se pretende resolver. TDA: para la definicin y representacin de tipos de datos (valores + operaciones), junto con sus propiedades. Objetos: Son TDA a los que se aade propiedades de reutilizacin y de comparticin de cdigo.
Si profundizamos ms al mundo de la programacin 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 programacin, define un conjunto de valores que una determinada variable puede tomar, as como las operaciones bsicas sobre dicho conjunto. Ahora veamos como se van relacionando estos conceptos. Los tipos de datos constituyen un primer nivel de abstraccin, ya que no se tiene en cuenta cmo se implementan o se representan realmente la informacin sobre la memoria de la mquina. Para el usuario, el proceso de implementacin o representacin 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 estn caracterizadas por el tipo de dato de los elementos guardados en la estructura y por la relacin definida sobre estos elementos. Al nivel de las estructuras de datos son totalmente irrelevantes las operaciones sobre un elemento en particular, solamente tienen carcter relevante las operaciones que envuelvan la estructura de forma global. Ejemplos de utilizacin de TDAs Algunos ejemplos de utilizacin de TDAs en programacin son: Conjuntos: Implementacin de conjuntos con sus operaciones bsicas (unin, interseccin y diferencia), operaciones de insercin, borrado, bsqueda... rboles: Implementacin de rboles de elementos, utilizados para la representacin interna de datos complejos. Pilas y Colas: Implementacin de los algoritmos FIFO y LIFO. 16
1.2 Estructuras de datos. Como ya sabemos, las computadoras fueron diseadas o ideadas como una herramienta mediante la cual podemos realizar operaciones de clculo complicadas en un lapso de mnimo tiempo. Pero la mayora de las aplicaciones de este fantstico invento del hombre, son las de almacenamiento y acceso de grandes cantidades de informacin. La informacin que se procesa en la computadora es un conjunto de datos, que pueden ser simples o estructurados. Los datos simples son aquellos que ocupan slo 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 coleccin de datos cuya organizacin 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 colocacin de los elementos y la manera en que se accede a ellos puede ser encapsulada.
1.2.1 Definicin. Una estructura de datos es una forma de organizar un conjunto de datos elementales (un dato elemental es la mnima informacin que se tiene en el sistema) con el objetivo de facilitar la manipulacin de estos datos como un todo o individualmente.
17
Una estructura de datos define la organizacin e interrelacionamiento de estos, y un conjunto de operaciones que se pueden realizar sobre l. Las operaciones bsicas son: Alta, adicionar un nuevo valor a la estructura. Baja, borrar un valor de la estructura. Bsqueda, encontrar un determinado valor en la estructura para realizar una operacin con este valor, en forma SECUENCIAL o BINARIO (siempre y cuando los datos estn 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 relacin a la simplicidad y eficiencia para la realizacin de cada operacin. De esta forma, la eleccin de la estructura de datos apropiada para cada problema depende de factores como la frecuencia y el orden en que se realiza cada operacin sobre los datos. 1.2.2 Clasificacin. Datos simples Binarios Bit Byte Numricos Entero Real Coma fija Coma flotante Alfanumricos Carcter Cadena 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 bsqueda rbol binario de bsqueda autoajustable rboles Rojo-Negro rboles AVL
Las estructuras de datos simples se pueden combinar de varias maneras para formar estructuras ms complejas. Las dos cases principales de estructuras de datos son las lineales y las no lineales, dependiendo de la complejidad de las relaciones lgicas que representan. Las estructuras de datos lineales incluyen 18
pilas, colas y listas ligadas lineales. Las estructuras de datos no lineales incluyen grafos y rboles. 1.2.2.2 Dinmicas y estticas. Las estructuras de datos dinmicas: No tienen las limitaciones o restricciones en el tamao de memoria ocupada que son propias de las estructuras estticas. Mediante el uso de un tipo de datos especifico, denominado puntero, es posible construir estructuras de datos dinmicas que no son soportadas por la mayora de los lenguajes, pero que en aquellos que si tienen estas caractersticas ofrecen soluciones eficaces y efectivas en la solucin 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 estticas: Son aquellas en las que el tamao ocupado en memoria se define antes de que el programa se ejecute y no puede modificarse dicho tamao durante la ejecucin del programa. Estas estructuras estn implementadas en casi todos los lenguajes. Su principal caracterstica 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, bolanos, enumerados y subrangos (los ltimos no existen en algunos lenguajes de programacin).
UNIDAD 2 ESTRUCTURAS LINEALES 2.1 Arreglos. Los arreglos se clasifican de acuerdo con el nmero de dimensiones que tienen. As se tienen los:
19
2.1.1 Definicin. Un arreglo (array) es una coleccin de datos del mismo tipo, que se almacenan en posiciones consecutivas de memoria y reciben un nombre comn. Para referirse a un determinado elemento de un array se deber utilizar un ndice, que especifique su posicin relativa en el array. Un arreglo es una coleccin finita, homognea y ordenada de elementos. Finita:Todo arreglo tiene un lmite;
20
es decir, debe determinarse cul ser el nmero mximo de elementos que podrn formar parte del arreglo. Homognea: Todos los elementos del arreglo deben ser del mismo tipo. Ordenada: Se puede determinar cul es el primer elemento, el segundo, el tercero,.... y el n-simo elemento. 2.1.2 Unidimensionales. Estn formados por un conjunto de elementos de un mismo tipo de datos que se almacenan bajo un mismo nombre, y se diferencian por la posicin 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];
Para acceder a valores especficos 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 tamao del arreglo. 2.1.3 Bidimensionales. 21
Este tipo de arreglos al igual que los anteriores es un tipo de dato estructurado, finito ordenado y homogneo. El acceso a ellos tambin 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 dimensin del arreglo representa las columnas, cada elemento contiene un valor y cada dimensin representa una relacin. La representacin en memoria se realiza de dos formas: almacenamiento por columnas o por renglones. Para determinar el nmero total de elementos en un arreglo bidimensional usaremos las siguientes frmulas: 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 direccin de memoria de un elemento se usan la siguiente formula: A[i,j] = base (A) + [((j - li2) R1 + (i + li1))*w]
22
x : array [1..5,1..7] of integer Para calcular la direccin 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 rengln a calcular j = ndice de la columna a calcular li1 = Lmite inferior de renglones li2 = Lmite inferior de columnas w = Nmero de bytes tipo componente
2.1.4 Multidimensionales. Este tambin 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 dimensin. Para determinar el nmero de elementos en este tipo de arreglos se usan las siguientes frmulas: 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 direccin de memoria se usa la siguiente formula: LOC A[i1,i2,i3,...,in] = base(A) + [(i1-li1)*R3*R4*Rn + (i2li2)*R3*R2*... (in - lin)*Rn]*w 2.1.5 Resolucin de problemas con arreglos.
23
Las operaciones para la resolucin de problemas en arreglos pueden clasificarse de la siguiente forma: Lectura Escritura Asignacin Actualizacin Ordenacin Bsqueda
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 haz x<--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 haz arreglo[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 haz arreglo[i]<--algn_valor
d) ACTUALIZACION Dentro de esta operacin 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 insercin, borrado y modificacin son los siguientes:
24
1.- Insertar. Si i< mensaje(arreglo contrario caso En arreglo[i]<--valor i<--i+1 entonces> 2.- Borrar. Si N>=1 entonces inicio 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 contrario i<--i+1 fin fin Si encontrado=falso entonces mensaje (valor no encontrado) 3.- Modificar. Si N>=1 entonces inicio i<--1 encontrado<--falso mientras i<=N y encontrado=false haz inicio Si arreglo[i]=valor entonces arreglo[i]<--valor_nuevo encontrado<--verdadero En caso contrario i<--i+1 fin fin
25
Las clases de implementacin 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 nmero de caracteres que contiene. Una cadena vaca es la que no tiene ningn carcter. Una constante de tipo cadena es un conjunto de caracteres vlidos encerrados entre comillas. Una variable de cadena es aquella cuyo contenido es una cadena de caracteres. El ltimo carcter de la cadena marca el fin de la cadena. Las variables de cadena se dividen en: Estticas. Su longitud se define antes de ejecutar el programa y no puede cambiarse a lo largo de este. Semiestticas. Su longitud puede variar durante la ejecucin del programa, pero sin sobrepasar un lmite mximo declarado al principio. Dinmicas. Su longitud puede variar sin limitacin dentro del programa.
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 posicin 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 slo por uno de los extremos. Como consecuencia, los elementos de una pila sern 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, tambin se le conoce como estructura LIFO (Last In, First Out: ltimo en entrar, primero en salir). 2.2.1 Definicin.
26
Una pila (stack en ingls) es una estructura de datos de tipo LIFO (del ingls Last In First Out, ltimo en entrar, primero en salir) que permite almacenar y recuperar datos. Se aplica en multitud de ocasiones en informtica debido a su simplicidad y ordenacin implcita en la propia estructura.
2.2.2 Operaciones. Para el manejo de los datos se cuenta con dos operaciones bsicas: apilar (push), que coloca un objeto en la pila, y su operacin inversa, retirar (o desapilar, pop), que retira el ltimo elemento apilado. En cada momento slo se tiene acceso a la parte superior de la pila, es decir, al ltimo objeto apliado (denominado TOS, top of stack en ingls). La operacin retirar permite la obtencin 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 analoga con objetos cotidianos, una operacin apilar equivaldra a colocar un plato sobre una pila de platos, y una operacin retirar a retirarlo. Las pilas suelen emplearse en los siguientes contextos: Evaluacin de expresiones en notacin postfija (notacin polaca inversa). Reconocedores sintcticos de lenguajes independientes del contexto Implementacin de recursividad.
2.2.3 Clases para la implementacin de pilas. El concepto de recursin es difcil 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 fotografa de una fotografa, o cuando en un programa de televisin 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 tpicos de estructuras de datos definidas de manera recursiva son los rboles binarios y las listas enlazadas.
27
La recursin se puede dar de dos formas: DIRECTA. Este tipo de recursin 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 implementacin de la recursividad. A continuacin se mostrarn algunos ejemplos. | | Factorial | | < N*(n-1)!, N>0 1, N=0
sp <--0 mientras n <> 1 haz push(pila,n) n<--n-1 mientras sp <> 0 haz factorial<--factorial*pop(pila) | | 0 , si a < b < | 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
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 sern extrados 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 muchsimos ejemplos de colas en la vida real, como por ejemplo: personas esperando en un telfono pblico, nios esperando para subir a un juego mecnico, estudiantes esperando para subir a un camin escolar, etc. 2.3.1 Definicin. Una cola es una estructura de datos, caracterizada por ser una secuencia de elementos en la que la operacin de insercin push se realiza por un extremo y la operacin de extraccin pop por el otro. Tambin se le llama estructura FIFO (del ingls First In First Out), debido a que el primer elemento en entrar ser tambin 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 atendern de modo convencional segn la posicin que ocupen. Hay 2 formas de implementacin: 1 2 Aadir un campo a cada nodo con su prioridad. Resulta conveniente mantener la cola ordenada por orden de prioridad. Crear tantas colas como prioridades haya, y almacenar cada elemento en su cola. Bicolas: son colas en donde los nodos se pueden aadir 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 insercin slo se hace por el final, aunque podemos eliminar al principio al final. Bicolas de salida restringida: Son aquellas donde slo se elimina por el final, aunque se puede insertar al principio y al final.
29
1 2
De dos elementos siempre se atender antes al que tenga mayor prioridad. Si dos elementos tienen la misma prioridad se atiende primero el que llego antes.
Realizacin 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 dems sern 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? Vaca =3 sino =8 3. crear nodo
4. asignacin de valor
7. fin 30
8. crear nodo
9. asignacin 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".
12. el apuntador externo "end" asigna al apuntador interno "next" apuntar a nulo
13.
fin
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
Algoritmo: 1. inicio manda a llamar a out 2. estado de cola? Vaca =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" sern 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
32
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 programacin muy delicada ya que con cualquier mal asignacin de apuntadores, tanto internos como externos, puede arruinar la estructura de los valores y hasta perder la informacin.
33
2.3.2.2 Colas circulares. Las colas lineales tienen un grave problema, como las extracciones slo pueden realizarse por un extremo, puede llegar un momento en que el apuntador A sea igual al mximo nmero de elementos en la cola, siendo que al frente de la misma existan lugares vacos, 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 representacin grfica de esta estructura es la siguiente:
La condicin de vaco 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 insercin. Under flow, cuando se requiera de una extraccin en la cola. Vacio
ALGORITMO DE INICIALIZACIN F < -- 0 A<-- 0 ALGORITMO PARA INSERTAR Si (F+1=A) (F=1 y A=mximo) entonces mensaje (overflow) en caso contrario inicio si A=mximo entonces A<--1 cola[A]<-- valor en caso contrario A <--A+1 cola[A]<-- valor si F=0 entonces F <-- 1 fin
34
ALGORITMO PARA EXTRAER Si F=0 entonces mensaje (underflow) en caso contrario x <-- cola[F] si F=A entonces F <-- 0 A<-- 0 en caso contrario si F=mximo 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. Grficamente representamos una bicola de la siguiente manera:
La primer variante slo acepta inserciones al final de la cola, y la segunda acepta eliminaciones slo al frente de la cola ALGORITMOS DE ENTRADA RESTRINGIDA Algoritmo de Inicializacin F < -- 1 A <-- 0 Algoritmo para Insertar Si A=mximo entonces mensaje (overflow) en caso contrario A <--A+1 cola[A]<-- valor
35
Algoritmo para Extraer Si F>A entonces mensaje (underflow) en caso contrario mensaje (frente/atrs) si frente entonces x <-- cola[F] F <-- F+1 en caso contrario x <-- cola[A] A <-- A-1 ALGORITMOS DE SALIDA RESTRINGIDA Algoritmo de Inicializacin F <--1 A <-- 0 Algoritmo para Insertar Si F>A entonces mensaje (overflow) en caso contrario mensaje (Frente/Atrs) si Frente entonces cola[F] <--valor en caso contrario A <-- A+1 cola[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: Insercin. 36
Extraccin. Las inserciones en la cola se llevarn a cabo por atrs de la cola, mientras que las eliminaciones se realizarn 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 implementacin de colas. Esta implementacin es esttica, es decir, da un tamao mximo fijo a la cola. No se incluye comprobacin 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 implementacin 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. Podra hacerse con un array secuencial, como se muestra en las siguientes figuras. 'Entrada' es la posicin 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 solucin nada efectiva es incrementar su tamao. Esta implementacin es sencilla pero totalmente ineficaz.
37
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. UNIDAD 3 LISTAS ENLAZADAS 3.1 Listas enlazadas. Una lista enlazada o encadenada es una coleccin 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 direccin de memoria del siguiente nodo de informacin si este existe. Un apuntador es la direccin 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 (vaco). A continuacin se muestra el esquema de una lista:
Las operaciones que podemos realizar sobre una lista enlazada son las siguientes: Recorrido. Esta operacin 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 direccin del tercer nodo, y as sucesivamente. Insercin. Esta operacin consiste en agregar un nuevo nodo a la lista. Para esta operacin se pueden considerar tres casos: Insertar un nodo al inicio. Insertar un nodo antes o despus de cierto nodo. 38
Insertar un nodo al final. Borrado. La operacin 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 informacin. Eliminar el nodo anterior o posterior al nodo cierta con informacin.
Bsqueda. Esta operacin 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 seccin se mostrarn 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 algn valor que lo diference de los dems 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 expresin 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 Creacin top<--NIL repite 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
Algoritmo para Recorrido p<--top mientras p<>NIL haz escribe(p(dato)) p<--p(liga:) Algoritmo para insertar al final p<--top mientras p(liga)<>NIL haz p<--p(liga) new(q) p(liga)<--q q(liga)<--NIL Algoritmo para insertar antes/despus de 'X' informacin p<--top mensaje(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
40
Algoritmo para borrar un nodo p<--top leer(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 creacin de una lista con nodo de cabecera new(cab) cab(dato)<--'*' cab(liga)<--NIL q<--cab repite new(p) leer(p(dato)) p(liga)<--NIL q<--p mensaje(otro nodo?) leer(respuesta) hasta respuesta=no Algoritmo de extraccin en una lista con nodo de cabecera leer(valor_a_borrar) p<--cab q<--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
41
q<--q(liga) 3.1.2 Dobles. Una lista doble , doblemente ligada es una coleccin 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 travs de la lista, segn 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 ms eficientes, los algoritmos que en esta seccin se traten sern sobre listas dobles circulares. En la figura siguiente se muestra un ejemplo de una lista doblemente ligada lineal que almacena nmeros:
En la figura siguiente se muestra un ejemplo de una lista doblemente ligada circular que almacena nmeros:
A continuacin mostraremos algunos algoritmos sobre listas enlazadas. Como ya se mencion, llamaremos li al puntero izquierdo y ld al puntero derecho, tambin usaremos el apuntador top para hacer referencia al primer nodo en la lista, y p para referenciar al nodo presente.
42
Algoritmo de creacin top<--NIL repite si top=NIL entonces new(p) lee(p(dato)) p(ld)<--p p(li)<--p top<--p en caso contrario new(p) lee(p(dato)) p(ld)<--top p(li)<--p p(ld(li))<--p mensaje(otro nodo?) lee (respuesta) hasta respuesta=no Algoritmo para recorrer la lista
43
Algoritmo para insertar despues de 'X' informacin p<--top mensaje(despues de ?) lee(x) repite si p(dato)=x entonces new(q) lee(q(dato)) q(ld)<--p(ld) q(li)<--p p(li(ld))<--q p(ld)<--q p<--top en caso contrario p<--p(ld) hasta p=top Algoritmo para borrar un nodo
p<--top mensaje(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) entonces top<--nil en caso contrario top<--top(ld) dispose(p) p<--top
44
3.1.3 Circulares. Las listas circulares tienen la caracterstica de que el ltimo elemento de la misma apunta al primero La siguiente figura es una representacin grfica de una lista circular.
Enseguida se mostrarn los algoritmos ms 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 creacin 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<--top repite escribe(p(dato)) p<--p(liga) hasta p=top
45
Algoritmo para insertar antes de 'X' informacin new(p) lee(p(dato)) si top=nil entonces top<--p p(liga)<--top en 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 despus de 'X' informacin new(p) lee(p(dato)) mensaje(despus de ?) lee(x) q<--top r<--top(liga) repite si q(dato)=x entonces q(liga)<--p p(liga)<--r q<--q(liga) r<--r(liga) hasta q=top
46
Algoritmo para borrar mensaje(valor a borrar ) lee(valor_a_borrar) q<--top r<--top p<--top mientras 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 mtodo de bsqueda permite accesar la informacin de manera ordenada a travs 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 bsqueda. A continuacin se presenta un ejemplo de multilistas. Supngase que se tiene un archivo en el cual cada registro almacena la siguiente informacin: Nombre Profesin Categora
Se tienen los datos de seis personas: Juan Daniel Jos Pascual Miguel Matemtico Fsico Matemtico Ingeniero Ingeniero 1 2 2 3 1
47
Felipe
Abogado
En este caso, la informacin de cada individuo puede accesarse por medio de su profesin y por medio de su categora, que son los atributos que permiten realizar bsqueda directa en el archivo. Como puede verse en la figura siguiente, se tiene una lista por profesin y una por categora. En general las multilistas son recomendables cuando la bsqueda se hace sobre un solo atributo. En caso de necesitarse una combinacin de atributos es preferible usar listas invertidas. 3.1.5 Clases para la implementacin de listas. Declaracin 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. Ntese, adems, que la definicin del tipo puntero PteroLista precede a la definicin del tipo registro NodoLista. Esta es la nica situacin en la que se permite utilizar un identificador (en este caso, NodoLista) antes de definirlo. Crear una lista enlazada vaca Para construir una lista enlazada debemos ser capaces de crear una lista vaca. PROCEDURE CrearLista( VAR Lista : TipoListaEnlazada );
48
BEGIN Lista := NIL; END Comprobar si una lista enlazada est vaca Dado que una lista enlazada vaca se representa mediante un puntero nulo, resulta sencillo determinar si una lista enlazada est vaca o no. FUNCTION ListaVacia( Lista : TipoListaEnlazad ) : boolean; BEGIN ListaVacia := Lista = NIL END Aadir un elemento al principio de una lista enlazada Uno de los mtodos para construir una lista enlazada consiste en aadir repetidamente elementos al principio de la lista, comenzando con una lista vaca. PROCEDURE AnnadirPrincLista( VAR Lista : TipoListaEnlazada; Elem : TipoElementosLista ); VAR PteroTemp : PteroLista; BEGIN new( PteroTemp ); PteroTerm^.Datos := Elem; PteroTemp^.Sig := Lista; Lista := PteroTerm END Recorrer una lista enlazada Una vez que se ha construido una lista enlazada podemos querer recorrerla desde el principio hasta el final, realizando algn 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 repeticin, utilizando los campos de enlaces para saltar de un nodo al siguiente.
49
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 ms 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 representacin grfica de un rbol binario es la siguiente:
4.1.1 Definicin. En ciencias de la computacin, 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 ms 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, tambin decimos que b es hijo de a). Slo puede haber un nico nodo sin padres, que llamaremos raz. 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 slo un nodo (es a la vez raz del rbol y hoja). Un nuevo rbol a partir de un nodo nr y k rboles de races con elementos cada uno, puede construirse estableciendo una relacin padre-hijo entre nr y cada una de las races de los k rboles. El rbol resultante de nodos tiene como raz el nodo nr, los nodos son los hijos de nr y el conjunto de nodos hoja est formado por la unin de los k conjuntos hojas iniciales. A cada uno de los rboles Ai se les denota ahora subrboles de la raz.
Una sucesin de nodos del rbol, de forma que entre cada dos nodos consecutivos de la sucesin haya una relacin de parentesco, decimos que es un recorrido rbol. 50
Existen dos recorridos tpicos 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 raz), se deben haber listado todos los de nivel n. Otros recorridos tpicos del rbol son preorden, postorden e inorden: El recorrido en preorden, tambin llamado orden previo consiste en recorrer en primer lugar la raz y luego cada uno de los hijos en orden previo. El recorrido en inorden, tambin llamado orden simtrico (aunque este nombre slo cobra significado en los rboles binarios) consiste en recorrer en primer lugar A1, luego la raz y luego cada uno de los hijos en orden simtrico. El recorrido en postorden, tambin llamado orden posterior consiste en recorrer en primer cada uno de los hijos en orden posterior y por ltimo la raz.
4.1.2 Representacin en memoria de rboles. Hay dos formas tradicionales de representar un rbol binario en memoria: Por medio de datos tipo punteros tambin conocidos como variables dinmicas o listas. Por medio de arreglos.
Sin embargo la ms utilizada es la primera, puesto que es la ms natural para tratar este tipo de estructuras. Los nodos del rbol binario sern representados como registros que contendrn como mnimo tres campos. En un campo se almacenar la informacin del nodo. Los dos restantes se utilizarn para apuntar al subrbol izquierdo y derecho del subrbol en cuestin. Cada nodo se representa grficamente de la siguiente manera:
51
El algoritmo de creacin 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) <-- nil crear(p) en caso contrario q(li) <-- nil mensaje("Rama derecha?") lee(respuesta) si respuesta="si" entonces new(p) q(ld)<--p crear(p) en caso contrario q(ld) <--nil fin INICIO new(p) raiz<--p crear(p) FIN 4.1.2.1 rboles generales. Los rboles representan las estructuras no lineales y dinmicas de datos ms importantes en computacin. Dinmicas porque las estructuras de rbol pueden cambiar durante la ejecucin de un programa. No lineales, puesto que a cada elemento del rbol pueden seguirle varios elementos. Los rboles pueden ser construidos con estructuras estticas y dinmicas. Las estticas son arreglos, registros y conjuntos, mientras que las dinmicas estn representadas por listas. La definicin de rbol es la siguiente: es una estructura jerrquica aplicada sobre una coleccin de elementos u objetos llamados nodos; uno de los cuales es conocido como raz. Adems se crea una relacin o parentesco entre los nodos dando lugar a trminos como padre, hijo, hermano, antecesor, sucesor,
52
ancestro, etc.. Formalmente se define un rbol de tipo T como una estructura homognea que es la concatenacin de un elemento de tipo T junto con un nmero finito de rboles disjuntos, llamados subrboles. Una forma particular de rbol puede ser la estructura vaca. La figura siguiente representa a un rbol general.
Se utiliza la recursin para definir un rbol porque representa la forma ms apropiada y porque adems es una caracterstica inherente de los mismos. Los rboles tienen una gran variedad de aplicaciones. Por ejemplo, se pueden utilizar para representar frmulas matemticas, para organizar adecuadamente la informacin, para construir un rbol genealgico, para el anlisis de circuitos elctricos y para numerar los captulos 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 continuacin se har una breve descripcin 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
A. B. SIMILARES Dos rboles binarios son similares cuando sus estructuras son idnticas, pero la informacin que contienen sus nodos es diferente. Ejemplo:
A. B. EQUIVALENTES Son aquellos rboles que son similares y que adems los nodos contienen la misma informacin. Ejemplo:
A. B. COMPLETOS Son aquellos rboles en los que todos sus nodos excepto los del ultimo nivel, tiene dos hijos; el subrbol izquierdo y el subrbol 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 raz. Recorrer el subrbol izquierdo en preorden. recorrer el subrbol derecho en preorden.
54
4.1.3.2 Inorden. INORDEN Recorrer el subrbol izquierdo en inorden. Examinar la raz. Recorrer el subrbol derecho en inorden.
4.1.3.3 Posorden. POSTORDEN Recorrer el subrbol izquierdo en postorden. Recorrer el subrbol derecho en postorden. Examinar la raz.
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 subrboles difieren a lo ms en 1. Se tiene que un rbol perfectamente balanceado es tambin balanceado; pero no es cierto lo contrario. Para estos rboles el mantenimiento del balanceo no es muy costoso, y las operaciones de bsqueda, insercin y borrado mantienen su orden O(log2n). Los rboles pueden estar balanceados por altura o por peso. Arbol balanceado por altura: en dnde todos los hijos o nodos hoja se intentan mantener a la misma distancia de la raz. Arbol balanceado por peso: en dnde los nodos ms visitados o utilizados se mantienen a poca distancia de la raz Un rbol es un grafo conexo y sin ciclos. Propiedades: Si G = (V,A) es un rbol de n vrtices, entonces: 1) Para todo par de vrtices x e y existe un nico camino de x a y. 55
2) Todas las aristas de G son puentes. 3) A = n - 1. 4) Todo rbol tiene al menos dos hojas (vrtices de grado uno). Caracterizaciones: Un grafo G=(V,A) es un rbol Para todo par de vrtices x e y existe un nico camino de x a y G es conexo y todas las aristas son puentes G es acclico y maximal (la adicin de una arista nueva origina un ciclo) G es conexo y A = n - 1 G es acclico y A = n - 1 Los rboles forman una de las subclases de las grficas de uso ms amplio. En el terreno de la computacin los rboles sirven para organizar y relacionar los datos de una base de datos. 4.1.5 Clases para la implementacin de rboles. Este tipo de estructura es usual incluso fuera del campo de la informtica. El lector seguramente conoce casos como los rboles gramaticales para analizar oraciones, los rboles genealgicos ,representacin de jerarquas, etc...La estructuracin en rbol de los elementos es fundamental dentro del campo de la informtica aplicndose en una amplia variedad de problemas como veremos ms adelante. En principio podemos considerar la estructura de rbol de manera intuitiva como una estructura jerrquica. Por tanto, para estructurar un conjunto de elementos ei en rbol, deberemos escoger uno de ellos e1 al que llamaremos raz del rbol. Del resto de los elementos se selecciona un subconjunto e2,...,ek estableciendo una relacin padre-hijo entre la raz 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 operacin para cada uno de estos elementos asignando a cada uno de ellos un nmero de 0 o ms hijos hasta que no tengamos ms elementos que insertar. El nico elemento que no tiene padre es e1,la raz 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 relacin de paternidad es una relacin uno a muchos. Para tratar esta estructura cambiaremos la notacin: Las listas tienen posiciones. Los rboles tienen nodos. Las listas tienen un elemento en cada posicin. 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 mayora de los problemas necesitaremos etiquetar los nodos. Es por ello por lo que a partir de ahora slo haremos referencia a rboles etiquetados).
56
4.2 Grafos Hoy en da podemos ver muchas cosas que nos pueden parecer de lo mas cotidianas, carreteras, lneas telefnicas, lneas de televisin por cable, el transporte colectivo metro, circuitos elctricos de nuestras casas, automviles, y tantas cosas mas; lo que no pensamos frecuentemente es que estos forman parte de algo que en matemticas 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 representacin grfica y en algunos casos, su representacin en algn programa informtico, as como en la memoria. En este trabajo, se explicando de manera muy sencilla los conceptos y algunas metodologas con un lenguaje no tan rebuscado para su mayor entendimiento. 4.2.1 Definicin. Desafortunadamente no existe una terminologa estandarizada en la teora 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 teora de grafos, pero en general se puede decir que un grafo como indica su nombre lo indica es la representacin (para nuestro caso) grfica de los datos de una situacin particular, ejemplo: Los datos contienen, en algunos casos, relaciones entre ellos que no es necesariamente jerrquica. Por ejemplo, supongamos que unas lneas areas realizan vuelos entre las ciudades conectadas por lneas como se ve en la figura anterior (ms adelante se presentaran grafos con estructuras de datos); la estructura de datos que refleja esta relacin 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", "asociacin 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 mayora de los textos de estructura de datos se utiliza el trmino "registro" al hacer referencia a archivos y "nodo" cuando se usan listas enlazadas, rboles y grafos. Tambin un grafo es una terna G = (V,A,j ), en donde V y A son conjuntos finitos, y j es una aplicacin que hace corresponder a cada elemento de A un par de elementos de V. Los elementos de V y de A se llaman, respectivamente, "vrtices" y "aristas" de G, y j asocia entonces a cada arista con sus dos vrtices. Esta definicin da lugar a una representacin grfica, en donde cada vrtice es un punto del plano, y cada arista es una lnea que une a sus dos vrtices.
57
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 vrtices 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 vrtices, 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> } Grficamente estas tres estructuras de vrtices y arcos se pueden representar de la siguiente manera:
Algunos de los principales tipos de grafos son los que se muestran a continuacin: Grafo regular: Aquel con el mismo grado en todos los vrtices. Si ese grado es k lo llamaremos k-regular. Por ejemplo, el primero de los siguientes grafos es 3-regular, el segundo es 2regular y el tercero no es regular Grafo bipartito: Es aquel con cuyos vrtices pueden formarse dos conjuntos disjuntos de modo que no haya adyacencias entre vrtices 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 vrtices. Un grafo completo con n vrtices se denota Kn. A continuacin 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 vrtices. 58
A continuacin ponemos los dibujos de K1,2, K3,3, y K2,5 Grafo nulo: Se dice que un grafo es nulo cuando los vrtices que lo componen no estn conectados, esto es, que son vrtices aislados.
Grafos Isomorfos: Dos grafos son isomorfos cuando existe una correspondencia biunvoca (uno a uno), entre sus vrtices de tal forma que dos de estos quedan unidos por una arista en comn.
Grafos Platnicos: Son los Grafos formados por los vrtices y aristas de los cinco slidos regulares (Slidos Platnicos), a saber, el tetraedro, el cubo, el octaedro, el dodecaedro y el icosaedro.
59
GRAFOS EULERIANOS. Para definir un camino euleriano es importante definir un camino euleriano primero. Un camino euleriano se define de la manera ms sencilla como un camino que contiene todos los arcos del grafo. Teniendo esto definido podemos hablar de los grafos eulerianos describindolos simplemente como aquel grafo que contiene un camino euleriano. Como ejemplos tenemos las siguientes imgenes: 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 vrtice V pertenece al conjunto de vrtices y es alcanzable por algn otro. Otra definicin que dejara esto ms claro sera: 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 Representacin de grafos en memoria. Los grafos se representan en memoria secuencial mediante matrices de adyacencia. Una matriz de adyacencia, es una matriz de dimensin n*n, en donde n es el nmero de vrtices que almacena valores booleanos, donde matriz M[i,j] es verdadero si y solo si existe un arco que vaya del vrtice y al vrtice j. Veamos el siguiente grafo dirigido:
60
Los grafos se representan en memoria enlazada mediante listas de adyacencia. Una lista de adyacencia, se define de la siguiente manera: Para un vrtice i es una lista en cierto orden formada por todos los vrtices 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 vrtice i. Veamos el siguiente grafo dirigido:
4.2.4 Clases para la implementacin de grafos. En esta seccin analizaremos algunas de las operaciones sobre grafos, como: Creacin. Insercin. Bsqueda. Eliminacin.
61
En esta seccin, 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=no p<--top mientras p<>NIL haz mensaje(tiene vrtices adyacentes p(dato) ?) lee(respuesta) si respueta=si entonces repite new(q) lee(q(dato)) q(ld)<--p(ld) p(ld)<--q mensaje(otro vrtice ?) 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
lee(q(dato)) p(la)<--q q(la)<--NIL mensaje(Hay vrtices adyacentes?) lee(respuesta) si respuesta=si entonces mensaje(Cuantos vrtices?) lee(nmero_vrtices) desde i=1 hasta nmero_vrtices haz new(p) lee(p(dato)) q(ld)<--p q<--q(ld) en caso contrario mensaje(no existe lista) ALGORITMO DE BUSQUEDA mensaje(vrtice a buscar) lee(vrtice_a_buscar) p<--top repite si p(dato)=vrtice_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(vrtice a borrar ?) lee(vrtice_a_borrar) p&Lt--top r<--p q<--p sw<--falso repite si p(dato)=vrtice_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
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)=vrtice_a_borrar entonces p(ld)<--q(ld) dispose(q) q<--p en caso contrario p<--p(ld) hasta p=NIL
64
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 Programacin Java, 3 Ed., Addison-Wesley, 2001. Arnow, D., G. Weiss, Introduccin a la Programacin con Java. Un enfoque Orientado a Objetos, Addison-Wesley, 2000. Eckel, B., Piensa en Java. 2 Edicin, Prentice-Hall, 2002. Horowitz, E., S. Sahni, Fundamentals of Data Structures in Pascal, Computer Science, 1994. Joyanes, L., I. Zahonero, Estructuras de Datos. Algoritmos, abstraccin y objetos, McGraw-Hill, 1998. Pea, Ricardo, Diseo de programas. Formalismo y abstraccin, Prentice-Hall, 1998. Weiss, M.A., Estructuras de datos y algoritmos, Addison-Wesley, 1995. Wirth, N., Algoritmos Iberoamericana, 1987. y Estructuras de Datos, Prentice-Hall
65