Estructuras de Datos y Algoritmos

Documentos relacionados
Estructuras de Datos y Algoritmos

UNIDAD 8 Tipos de datos dinámicos: Punteros Asignación dinámica de memoria. Uso de punteros. Inicialización y asignación de punteros.

TAD Lineales: Pila, Cola y Lista

Tipos algebraicos y abstractos. Algoritmos y Estructuras de Datos I. Tipos algebraicos

Árboles y esquemas algorítmicos. Tema III

UNIDAD 8 Tipos de datos dinámicos: Punteros Asignación dinámica de memoria. Uso de punteros. Inicialización y asignación de punteros.

APUNTADORES. Un apuntador es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable.

El TAD Árbol. El TAD Árbol

El TAD Grafo. Objetivos. Contenidos

6. Listas Generalizadas

Tipos Recursivos de Datos

TAD Lineales: Pila, Cola y Lista

Estructura de Datos. Listas Enlazadas

Instituto de Computación. Facultad de Ingeniería. Universidad de la República Examen de Programación 2 03 de Agosto de 2006 Generalidades:

Tema 6: Estructuras de datos recursivas

Estructuras Dinámicas de datos.

Tema 8. Listas. José M. Badía, Begoña Martínez, Antonio Morales y José M. Sanchiz

Ejercicios del Tema 3 Estructuras jerárquicas: Árboles

Estructuras de Datos Dinámicas Contenido del Tema

LISTAS. Prof. Ing. M.Sc. Fulbia Torres

Implementación de diccionarios sobre Trie en C++

ASIGNATURA: (TIS-106) Estructuras de Datos II DOCENTE: Ing. Freddy Melgar Algarañaz TEMA 2. Árboles binarios

Estructura de datos y algoritmos. Tema IV: TIPOS DE DATOS ABSTRACTOS DINÁMICOS LINEALES

TEMA 3. Árboles. Objetivos. Contenidos. Bibliografía. Básica

1.2.4 Listas enlazadas

Examen de Programación II (Ingeniería Informática)

Ejercicio 2 Considere la representación para Lista de Naturales y Árbol Binario de Naturales de la Figura 1.

ESTRUCTURA DE DATOS. ABB Arboles de Búsqueda Binaria

Estructura de datos y de la información Boletín de problemas - Tema 10

4. Pilas ESTRUCTURAS DE DATOS 1

Análisis amortizado El plan:

Tema 08: TAD Árbol. M. en C. Edgardo Adrián Franco Martínez edgardoadrianfrancom

Estructuras de Datos y Algoritmos

TEMA 5 El tipo grafo. Tipo grafo

Universidad de Alcalá Departamento de Ciencias de la Computación

UNIVERSIDAD AUTONOMA DE MADRID ESCUELA POLITÉCNICA SUPERIOR ESTRUCTURAS DE DATOS Y ALGORITMOS

Segundo Parcial de Programación 2 7 de junio de 2017

Departamento de Informática Universidad de Valladolid Campus de Segovia TEMA 3: ESTRUCTURAS DINÁMICAS LINEALES. LISTAS ENLAZADAS, PILAS Y COLAS

Tema 6. Gestión dinámica de memoria

Árboles balanceados (AVL) Tablas de dispersión (Hash) Colas de prioridad (Heap)

LISTAS DOBLES y multiples

Capítulo 5. LISTAS. 5.1 Listas y listas vinculadas. Una lista es una colección lineal de elementos.

6. El TDA Lista Implementación con listas enlazadas. es de tipo genérico T. Pueden existir elementos repetidos (a diferencia de los conjuntos).

El TAD Grafo. El TAD Grafo

Estructura de Datos. Árboles Binarios de Búsqueda ABB. Primer Semestre, 2010

Programación. Orienta a Objetos con C++

Ingeniera de Sistemas: Luz Esperanza Espitia Tutora de Estructura de datos.

Árboles n-arios. Lección 15

Algoritmos y Programación II Curso 2006

ESTRUCTURAS DE DATOS Y ALGORITMOS

Análisis de algoritmos

ÁRBOLES CRISTIAN ALFREDO MUÑOZ ÁLVAREZ JUAN DAVID LONDOÑO CASTRO JUAN PABLO CHACÓN PEÑA EDUARDO GONZALES

Listas, Pilas y Colas

Árboles generales. Un árbol es una estructura no lineal acíclica utilizada para organizar información de forma eficiente. La definición es recursiva:

Tecnólogo Informático- Estructuras de Datos y Algoritmos- 2009

LISTAS ENLAZADAS FUNDAMENTOS TEORICOS

Tema 4. Estructuras no lineales de datos: árboles

Estructuras de datos Listas y árboles

Estructuras de Datos II (I.T. Informática de Gestión y Sistemas) Boletín nº 1 Tipos Abstractos de Datos: especificaciones algebraicas

Tipos de datos algebraicos

Tema 7: Árbol Binario

EJERCICIO 2 (3 PUNTOS) A) Sea el árbol binario AVL de la figura siguiente: B) Dada la estructura de la figura siguiente:

Árboles n-arios de búsqueda. Lección 16

Dualidad 1. 1 Formas simétricas. 2 Relación primal-dual. 3 Dualidad: el caso general. 4 Teoremas de dualidad. 5 Condiciones de holgura complementaria.

ESTRUCTURAS DE DATOS II

Tema 14: ÁRBOLES Algoritmos y estructuras de datos I - Tema 14 1

A l g o r i t m o y E s t r u c t u r a d e D a t o s Ing. en Sistemas de Información - 1º año -

GRAFOS. Tomado de: Joyanes Aguilar Luis, Estructuras de datos en Java. CASOS

Estructura de datos y algoritmos. Tema V TDA DINÁMICOS NO LINEALES: Árboles: árboles binarios

Estructura de Datos. Unidad de Aprendizaje: Unidad de Competencia II: Estructuras de Datos Lineales. M. en C. Edith Cristina Herrera Luna

Estructuras de datos utilizando JAVA

UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO

RESUMEN DE ALGORITMOS PROBABILÍSTICOS

Estructuras de datos: Árboles binarios de

Universidad Autónoma del Estado de México 2016, Año del 60 Aniversario de la Universidad Autónoma del Estado de México

A l g o r i t m o y E s t r u c t u r a d e D a t o s Ing. en Sistemas de Información - 1º año -

Parte de Algoritmos de la asignatura de Programación Master de Bioinformática. Búsqueda exhaustiva

Solución práctico 6 Tipos Abstractos de Datos Lista, Pila y Cola

Estructuras lineales de datos

Segundo parcial de Programación 2

INTRODUCIR FORMULAS EN EXCEL

Este material es de uso exclusivo para estudio, los textos fueron tomados textualmente de varios libros por lo que está prohibida su impresión y

PRÁCTICA No. 9 RECORRIDOS EN ÁRBOLES BINARIOS

Estructuras de datos: Árboles binarios de

B) Contestar Verdadero o Falso a las siguientes preguntas, justificando la respuesta:

14. ÁRBOLES Fundamentos y terminología básica

Tema 2: Grafos y Árboles. Algoritmos y Estructuras de Datos 3

Tema 9: Declaraciones de tipos y clases

Transcripción:

Estructuras de Datos y Algoritmos Tema 4.3. Tipos de datos lineales. Listas Prof. Dr. P. Javier Herrera

Contenido Listas: Conceptos generales Operaciones básicas Especificación algebraica Implementación dinámica Extensión de operaciones Extensión de la especificación algebraica Extensión de la implementación dinámica 2

Listas: Conceptos generales Vivimos rodeados de listas: la lista de la compra, la lista de regalos de boda, la lista de libros para el próximo curso, etc., siendo el denominador común de todas estas listas el establecer una ordenación entre sus elementos. Las listas son las estructuras de datos lineales más flexibles, puesto que su única característica es imponer un orden entre los elementos almacenados en ellas. Según este criterio, las pilas y las colas serían casos particulares de listas, donde se ha restringido la forma de acceso a la estructura. No existe una visión unánime de las listas como TAD, con un conjunto básico de operaciones. Se trata de un tipo de datos parametrizado, donde el comportamiento de las operaciones sobre los valores del tipo lista es independiente de la naturaleza de los elementos que la componen. 3

Operaciones básicas Un posible TAD de las listas cuenta con las siguientes operaciones: crear la lista vacía, generar una lista unitaria formada por un elemento dado, añadir un elemento por la izquierda, añadir un elemento por la derecha, consultar el elemento más a la izquierda, consultar el elemento más a la derecha, eliminar el elemento más a la izquierda, eliminar el elemento más a la derecha, determinar si una lista es vacía, concatenar dos listas, y calcular la longitud de una lista. 4

Especificación algebraica especificación LISTAS[ELEM] usa BOOLEANOS, NATURALES tipos lista operaciones [ ] : lista { constructora } _ : _ : elemento lista lista { constructora } [ _ ] : elemento lista _ # _ : lista elemento lista izquierdo : lista p elemento elim-izq : lista p lista derecho : lista p elemento elim-der : lista p lista es-lista-vacía? : lista bool _ ++ _ : lista lista lista longitud : lista nat 5

Especificación algebraica variables e, f : elemento x, y, z : lista ecuaciones [e] = e : [ ] x # e = x ++ [e] izquierdo([ ]) izquierdo(e : x) = error = e elim-izq([ ]) elim-izq(e : x) = error = x derecho([ ]) = error derecho(e : [ ]) = e derecho(e : f : x) = derecho(f : x) 6

Especificación algebraica elim-der([ ]) = error elim-der(e : [ ]) = [ ] elim-der(e : f : x) = e : elim-der(f : x) es-lista-vacía?([ ]) = cierto es-lista-vacía?(e : x) = falso [ ] ++ y = y (e : x) ++ y = e : (x ++ y) longitud([ ]) = 0 longitud(e : x) = 1 + longitud(x) fespecificación También podemos considerar como constructoras la operación que crea la lista vacía y la que añade un elemento por la derecha (situación simétrica a la anterior); o bien elegir la lista vacía, la operación de construcción de la lista unitaria y la operación de concatenación. 7

Implementación dinámica Los elementos de una lista se representan mediante una sucesión de nodos doblemente enlazados: cada nodo, además del valor del elemento concreto almacenado, contiene enlaces al nodo siguiente y al anterior en la sucesión. La ventaja de tener estos dobles enlaces es que así se pueden eliminar elementos por ambos extremos de la lista con un coste en tiempo constante. Una lista será un registro con un campo que guarda la longitud de la lista y enlaces a los nodos más a la izquierda y más a la derecha de la sucesión. 8

Implementación dinámica tipos enlace-lista nodo-lista lista ftipos = puntero a nodo-lista = reg valor : elemento sig, ant : enlace-lista freg = reg longitud : nat izquierdo, derecho : enlace-lista freg 9

Implementación dinámica La lista vacía no tiene elementos, por lo que la longitud es cero, y como no hay elementos, los punteros izquierdo y derecho son nulos. fun lista-vacía() dev l : lista { O 1 } l.longitud := 0 l.izquierdo := nil l.derecho := nil ffun Una lista es vacía cuando los punteros (uno o ambos, pues ambas condiciones son equivalentes) son nulos pues eso significa que no hay nodos en la estructura. fun es-lista-vacía?(l : lista) dev r : bool { O 1 } r := (l.izquierdo = nil) ffun 10

Implementación dinámica Añadir un elemento por la izquierda consiste en reservar memoria para un nuevo nodo, almacenar en él el nuevo elemento, y enlazarlo con la estructura, distinguiendo el caso en el que la lista inicial sea vacía. En cualquier caso la longitud de la lista aumenta en una unidad. proc añadir-izq(e e : elemento, l : lista) { O 1 } var p : enlace-lista reservar(p) p.valor := e ; p.ant := nil si l.izquierdo = nil entonces { l es vacía } p.sig := nil ; l.derecho := p si no p.sig := l.izquierdo ; (l.izquierdo).ant := p fsi l.izquierdo := p l.longitud := l.longitud + 1 fproc 11

Implementación dinámica Añadir un elemento por la derecha es la operación simétrica. proc añadir-der(l : lista, e e : elemento) { O 1 } var p : enlace-lista reservar(p) p.valor := e ; p.sig := nil si l.derecho = nil entonces p.ant := nil ; l.izquierdo := p si no p.ant := l.derecho ; (l.derecho).sig := p fsi l.derecho := p l.longitud := l.longitud + 1 fproc 12

Implementación dinámica Construir una lista unitaria a partir de un elemento dado consiste en crear una nueva lista con un único nodo que es apuntado tanto por izquierdo como por derecho. La longitud es 1. fun unitaria(e : elemento) dev l : lista { O 1 } var p : enlace-lista reservar(p) p.valor := e p.ant := nil ; p.sig := nil l.izquierdo := p ; l.derecho := p l.longitud := 1 ffun 13

Implementación dinámica El elemento más a la izquierda de una lista no vacía se obtiene accediendo al campo valor del nodo apuntado por izquierdo. Si la lista es vacía se produce un mensaje de error. La operación derecho es simétrica. fun izquierdo(l : lista) dev e : elemento { O 1 } si l.izquierdo = nil entonces error(lista vacía) si no e := (l.izquierdo).valor fsi ffun fun derecho(l : lista) dev e : elemento { O 1 } si l.derecho = nil entonces error(lista vacía) si no e := (l.derecho).valor fsi ffun 14

Implementación dinámica Para eliminar el izquierdo se libera el primer nodo de la estructura, dejándola bien enlazada. Las operaciones derecho y elim-der son simétricas a las dos anteriores. proc elim-izq(l : lista) { O 1 } var p : enlace-lista si l.izquierdo = nil entonces error(lista vacía) si no p := l.izquierdo ; l.izquierdo := p.sig si l.izquierdo = nil entonces l.derecho := nil si no (l.izquierdo).ant := nil fsi l.longitud := l.longitud 1 liberar(p) fsi fproc 15

Implementación dinámica La operación elim-der es simétrica. proc elim-der(l : lista) { O 1 } var p : enlace-lista si l.derecho = nil entonces error(lista vacía) si no p := l.derecho ; l.derecho := p.ant si l.derecho = nil entonces l.izquierdo := nil si no (l.derecho).sig := nil fsi l.longitud := l.longitud 1 liberar(p) fsi fproc 16

Implementación dinámica La lista resultado de concatenar las dos listas que recibe como argumento, comienza siendo una copia de la primera lista. A continuación se recorre la sucesión de nodos de la segunda lista, añadiendo cada elemento por la derecha a la lista resultado. El coste en tiempo de concatenar es lineal respecto a la suma de las longitudes de las listas concatenadas. fun concatenar(x, y : lista) dev z : lista { O longitud x longitud y } var p : enlace-lista z := lista-vacía() ; p := x.izquierdo mientras p nil hacer añadir-der(z, p.valor) ; p := p.sig fmientras p := y.izquierdo mientras p nil hacer añadir-der(z, p.valor) ; p := p.sig fmientras ffun 17

Implementación dinámica Si se implementara la operación concatenar mediante un procedimiento, se podría conseguir un coste constante modificando el primer argumento para que también fuera el resultado, para lo cual bastaría encadenar el nodo derecho de x con el izquierdo de y, y sumar las dos longitudes. La longitud de una lista se obtiene consultando el campo correspondiente, con un coste en tiempo constante. fun longitud(l : lista) dev n : nat { O 1 } n := l.longitud ffun 18

Extensión de operaciones Extender la especificación para considerar las siguientes operaciones: determinar si un elemento aparece en una lista, localizar la posición de un elemento (devolviendo 0 si el elemento no está), calcular el número de repeticiones de un elemento, eliminar todas las apariciones de un elemento, determinar si dos listas son iguales, determinar si una lista es capicúa, consultar el elemento en una posición, insertar un elemento en una posición, eliminar el elemento en una posición, y modificar el elemento en una posición. 19

Extensión de la especificación algebraica especificación LISTAS+[ELEM=] usa LISTAS[ELEM=], NATURALES, BOOLEANOS operaciones está? : elemento lista bool posición : elemento lista nat repeticiones : elemento lista nat eliminar : elemento lista lista _ == _ : lista lista bool es-capicúa? : lista bool _ [ _ ] : lista nat p elemento insertar : lista nat elemento p lista eliminar : lista nat p lista modificar : lista nat elemento p lista variables e, f : elemento ; x, y, z : lista ; i : nat 20

Extensión de la especificación algebraica ecuaciones está?(e, [ ]) = falso está?(f, e : x) = f == e está?(f, x) posición(e, x) = 0 está?(e, x) posición(e, e : x) = 1 posición(e, f : x) = 1 + posición(e, x) e f está?(e, x) repeticiones(e, [ ]) = 0 repeticiones(e, e : x) = 1 + repeticiones(e, x) repeticiones(e, f : x) = repeticiones(e, x) e f 21

Extensión de la especificación algebraica eliminar(e, [ ]) = [ ] eliminar(e, e : x) = eliminar(e, x) eliminar(e, f : x) = f : eliminar(e, x) e f [ ] == [ ] = cierto [ ] == e : x = falso e : x == [ ] = falso e : x == f : y = e == f x == y es-capicúa?([ ]) = cierto es-capicúa?(e : [ ]) = cierto es-capicúa?(e : x) = e == derecho(x) es-capicúa?(elim-der(x)) es-lista-vacía?(x) 22

Extensión de la especificación algebraica x[i] = error i == 0 i > longitud(x) (e : x)[1] = e (e : x)[i] = x[i 1] 1 < i i longitud(e : x) insertar(x, i, e) = error i == 0 i > longitud(x) + 1 insertar(x, 1, e) = e : x insertar(e : x, i, f) = e : insertar(x, i 1, f) 1 < i i longitud(e : x) + 1 eliminar(x, i) = error i == 0 i > longitud(x) eliminar(e : x, 1) = x eliminar(e : x, i) = e : eliminar(x, i 1) 1 < i i longitud(e : x) modificar(x, i, f) = insertar(eliminar(x, i), i, f) fespecificación 23

Extensión de la implementación dinámica La declaración de tipos es la misma. Para averiguar si un elemento está en una lista se recorre la estructura de nodos enlazados hasta que se encuentre el elemento o se acabe la estructura. En cada nodo del recorrido se consulta si el elemento en el campo valor es igual al elemento e dado. fun está?(e : elemento, l : lista) dev b : bool { O longitud l } var p : enlace-lista b := falso p := l.izquierdo mientras p nil b hacer b := (e = p.valor) p := p.sig fmientras ffun 24

Extensión de la implementación dinámica La función para localizar un elemento es muy similar. Al recorrer la lista vamos guardando en una variable auxiliar i la posición del elemento en el que nos encontramos. Si el valor apuntado es igual al que buscamos, asignamos el valor de i al parámetro de salida n. fun posición(e : elemento, l : lista) dev n : nat { O longitud l } var p :enlace-lista n := 0 ; i := 0 ; p := l.izquierdo mientras p nil n = 0 hacer si e = p.valor entonces n := i fsi p := p.sig i := i + 1 fmientras ffun 25

Extensión de la implementación dinámica Para contar el número de apariciones de un elemento hay que recorrer toda la lista. fun repeticiones(e : elemento, l : lista) dev n : nat { O longitud l } var p : enlace-lista n := 0 p := l.izquierdo mientras p nil hacer si e = p.valor entonces n := n + 1 fsi p := p.sig fmientras ffun 26

Extensión de la implementación dinámica Para eliminar todas las apariciones de un elemento se recorre la estructura de nodos enlazados. Cuando se encuentra un nodo con un elemento igual al que hay que eliminar, hay que modificar todos los enlaces para evitar dicho nodo que se libera, tratando apropiadamente los casos en que éste es el primero o el último. La longitud va decreciendo a medida que se eliminan nodos. proc eliminar(e : elemento, l : lista) { O longitud l } var p, q : enlace-lista p := l.izquierdo mientras p nil hacer si p.valor = e entonces si p = l.izquierdo entonces l.izquierdo := p.sig p.sig.ant := nil si no p.ant.sig := p.sig fsi 27

Extensión de la implementación dinámica si p = l.derecho entonces l.derecho := p.ant p.ant.sig := nil si no p.sig.ant := p.ant fsi q := p p := p.sig liberar(q) l.longitud := l.longitud 1 si no p := p.sig fsi fmientras fproc 28

Extensión de la implementación dinámica Para determinar si dos listas son iguales, primero se comprueba si tienen la misma longitud. Si es así, se utilizan dos punteros auxiliares p y q para recorrer cada una de las listas, comprobando si los elementos apuntados por ambos son iguales. fun igual(x, y : lista) dev b : bool { O longitud x } var p, q : enlace-lista si x.longitud y.longitud entonces b := falso si no b := cierto p := x.izquierdo ; q := y.izquierdo mientras p nil b hacer b := (p.valor = q.valor) p := p.sig ; q := q.sig fmientras fsi ffun 29

Extensión de la implementación dinámica Para comprobar si una lista es capicúa utilizamos dos enlaces: p recorrerá los elementos de la lista de izquierda a derecha, y q recorrerá los elementos de derecha a izquierda. Ya que no se puede comprobar fácilmente cuando se cruzan los punteros en su recorrido, utilizamos una variable m para contar cuantos elementos hay desde p hasta q (ambos incluidos). fun es-capicúa?(l : lista) dev b : bool { O longitud l } var p, q : enlace-lista b := cierto p := l.izquierdo ; q := l.derecho m := l.longitud mientras m > 1 b hacer b := (p.valor = q.valor) p := p.sig ; q := q.ant m := m 2 fmientras ffun 30

Bibliografía Martí, N., Ortega, Y., Verdejo, J.A. Estructuras de datos y métodos algorítmicos. Ejercicios resueltos. Pearson/Prentice Hall, 2003. Capítulo 5 Peña, R.; Diseño de programas. Formalismo y abstracción. Tercera edición. Prentice Hall, 2005. Capítulo 6 (Estas transparencias se han realizado a partir de aquéllas desarrolladas por los profesores Clara Segura, Alberto Verdejo y Yolanda García de la UCM, y la bibliografía anterior) 31