La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Estructura de Datos En C++ Dr. Romeo Sánchez Nigenda. Oficina: 1er. Piso del CIDET. Oficina.

Presentaciones similares


Presentación del tema: "Estructura de Datos En C++ Dr. Romeo Sánchez Nigenda. Oficina: 1er. Piso del CIDET. Oficina."— Transcripción de la presentación:

1 Estructura de Datos En C++ Dr. Romeo Sánchez Nigenda. Oficina: 1er. Piso del CIDET. Oficina con Dr. Oscar Chacón Horas de Tutoría: 10am-11am Martes y Jueves, 3:30pm-4:30pm Miércoles, 2:00pm-4:00pm Viernes. Website: Sesiones: 48

2 Objetivo General: Conocerá y manejará las estructuras internas de información Temario: 1. Conceptos Básicos 2. La Pila 3. Colas 4. Recursión 5. Listas 6. Árboles 7. Ordenamiento 8. Búsqueda 9. Administración de Almacenamiento Total a calificar: 110 puntos. 40% Tareas 30% Examen Parcial 30% Examen Final 10% Participación 40% Tareas 30% Examen Parcial 30% Examen Final 10% Participación

3 Material de apoyo: Estructura de Datos con C y C++. Yedidyah Langsam, Moshe J. Augenstein, Aaron M. Tenenbaum, Brooklyn College Segunda Edición, Prentice-Hall. Algorithms. Third Edition. Parts 1-4, Fundamentals Data Structures Sorting Searching Robert Sedgewick. Estructura de Datos. Román Martínez, Elda Quiroga. Thomson Learning. Cualquier libro de Estructura de Datos! Software: Compiladores GCC (GNU Compiler Collection) IDEs (Integrated Development Environment):

4 3. Listas Objetivo: El alumno manejará estructuras de datos lineales y dinámicas, y entenderá las ventajas de utilizarlas para optimizar el uso de espacio en memoria. Temario: Definición y conceptos utilizados Operaciones con listas Listas circulares Listas doblemente ligadas Aplicaciones

5 Listas Cuáles son las desventajas de usar almacenamiento secuencial para presentar filas y colas? Una lista vinculada (linked list) es una estructura dinámica de nodos de datos los cuales se representan como una secuencia. En su forma más simple, cada nodo se compone: De un área de datos o información De una referencia (link) al siguiente nodo en la secuencia Se puede acceder a la lista vinculada por medio de una variable apuntador externa, que contenga la dirección del primer elemento en la lista. El último nodo en la lista apunta al valor null para señalar el término de la secuencia. inf sig inf sig inf sig null inf sig cabeza

6 Cada registro de una lista vinculada es a menudo llamado un elemento o nodo El campo de cada nodo que contiene la dirección al siguiente nodo es usualmente llamado el siguiente link o siguiente puntero (next) Los campos remanentes contienen los datos, información, o valores La cabeza (head) de la lista es su primer elemento La cola (tail) de la lista se puede referir al resto de los elementos después de la cabeza, o al último nodoListas

7 Características: La estructura permite inserción y remoción de elementos eficientemente de cualquier posición en la secuencia El principal beneficio entonces de una lista sobre arreglos es que sus elementos no necesitan reacomodarse cada vez que se actualiza la lista Una lista sin nodos se denomina lista vacía, el apuntador externo a la lista es null Sin embargo, listas simples no permiten acceso randomizado o indexación, por lo que operaciones básicas como obtener el último nodo en la lista o encontrar un nodo puede requerir escanear la mayoría o todos sus elementosListas

8 Listas: Operaciones básicas Inserción en la parte delantera de la lista 6 inf sig 3 inf sig 8null inf sig cabeza inf sig Se obtiene memoria para el nuevo nodo: Se establecen los valores (datos) del nodo: Se establece el link (sig) del nodo al primer elemento en la lista: P & Nodo vacío 12 infsig P & P->sig = cabeza 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig P &

9 Operaciones básicas: Inserción Se actualiza el apuntador externo cabeza al nuevo nodo insertado: El valor de P es irrelevante antes y después de la inserción del elemento a la lista: El algoritmo básico de inserción queda entonces: p = creaNodo (); info (p) = 12 //Datos nuevos next (p) = cabeza cabeza = p cabeza = P 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig P 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig Qué pasa cuando la lista está vacía?

10 Operaciones básicas: Remoción 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig Se hace referencia al primer nodo en la lista a través de un apuntador: P = cabeza La cabeza de la lista debe apuntar al siguiente nodo en la secuencia: cabeza = P->sig Se guardan los valores a retornar en una variable: x = P->info 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig P 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig P

11 Operaciones básicas: Remoción En este momento se considera que P ya ha sido removido de la lista, pues a pesar que conserva un apuntador a un nodo en la lista, no es posible acceder a P a través del apuntador externo cabeza. El siguiente paso sería liberar la memoria que P usa: liberaNodo(P) El algoritmo de remoción es básicamente opuesto al de inserción: P = cabeza Cabeza = next(P) X = info(P) liberaNodo(P) 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig P

12 Operaciones Básicas: Travesar 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig Se obtiene un apuntador al primer elemento (cabeza) de la lista: P = cabeza MIENTRAS que el apuntador no sea nulo (null), se lee el campo de información: X = P -> info Se actualiza la variable apuntador al siguiente elemento en la lista: P = P -> sig 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig P 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig PPPP ………

13 Operaciones Básicas: Implementación struct nodo{ int info; struct nodo * sig; }; typedef struct nodo *NODEPTR; NODEPTR cabeza=NULL; Definición de un nodo simple usando estructuras en C: Inicialización de una lista vacía, usando un apuntador externo: NODEPTR creaNodo(void){ NODEPTR p = (NODEPTR) malloc (sizeof(struct nodo)); return(p); } void liberaNodo(NODEPTR p){ free(p); } Asignación de Memoria Liberación de Memoria

14 Operaciones Básicas: Implementación void traversaLista(NODEPTR cabeza){ NODEPTR p = cabeza; while(p!=NULL){ cout info<sig; } 6 inf sig 3 inf sig 8null inf sig cabeza 12 infsig PPP … … … P

15 Operaciones Básicas: Implementación void insertaNodo(NODEPTR * cabeza, int valor){ NODEPTR p =creaNodo(); p->info=valor; p->sig = *cabeza; *cabeza=p; } int borraNodo(NODEPTR * cabeza){ int value = -1; if(*cabeza!=NULL){ NODEPTR p = *cabeza; *cabeza= p->sig; value = p->info; liberaNodo(p); } return value; } NODEPTR cabeza=NULL; insertaNodo(&cabeza,1); traversaLista(cabeza); borraNodo(&cabeza);

16 6 inf sig 3 inf sig 8null inf sig cabeza Operaciones Básicas: Implementación Inserta después de un nodo P: P void insertaDespuesNodo(NODEPTR * P, int valor){ NODEPTR q =creaNodo(); q->info=valor; q->sig=(*P)->sig; (*P)->sig=q; } valor inf sig q inf sig q 3 inf sig 8null inf sig P valor inf sig q 3 inf sig 8null inf sig P valor inf sig q

17 6 inf sig 3 inf sig 8null inf sig cabeza Operaciones Básicas: Implementación Elimina después de un nodo P: P int deleteDespuesNodo(NODEPTR * P){ q=(*P)->sig; valor = q->info; (*P)->siq=q->sig; liberaNodo(q); } 3 inf sig P 8null inf sig 8null inf sig null …

18 Listas Implementando Colas 6 inf sig 3 inf sig 8null inf sig cabeza P cola Se consideran dos apuntadores, uno al principio de la lista para remover elementos. El segundo al final de la lista para insertar (FIFO). Pseudocódigo para remover un elemento: remueve(Cola q){ if(!colaVacia(q)){ p = q.cabeza x = info(p) // Almacena 6 en X para retornarlo q.cabeza = next(P) //cabeza apunta ahora al segundo nodo if(q.cabeza==NULL){ q.cola=NULL //Si eliminamos el ultimo, actualiza cola } liberaNodo(p); }

19 Listas Implementando Colas 6 inf sig 3 inf sig 8null inf sig cabeza P cola Pseudocódigo para insertar un elemento: inserta(Cola q, Elemento x){ p = creaNodo() info(p) = x // Almacena el valor del nuevo elemento en el nodo next(p) = NULL //Nuevo elemento es el último if(q.cola==NULL){ q.cabeza = p; //Cola vacia, entonces p es el primero }else{ next(q.cola) = p //El siguiente de cola apunta al nuevo } q.cola = p //Cola se actualiza al ultimo elemento }

20 Ejemplo: Remueve X elementos Pseudocódigo para remover X elementos: q = NULL P = cabeza While(P!=NULL){ If(info(p) == X){ if(q==NULL){ cabeza = next(P) P=cabeza; }else{ p = next(P); deleteDespuesNodo(q) } } else{ q=p; p = next(p) } 6 inf sig X inf sig 8 inf sig cabeza Xnull inf sig

21 Listas Circulares 6 inf sig 3 inf sig 8 inf sig 12 infsig Una convención es que el apuntador externo apunte al último nodo en la lista, para así también acceder al primer nodo con el campo sig del último nodo. Ejemplo: Pilas como listas circulares, donde el primer nodo es el tope de la Pila. La pila está vacía si: apunta = NULL int estaVacia(NODEPTR apunta) { return (apunta == NULL); } apunta

22 Listas Circulares: Pilas 6 inf sig 3 inf sig X inf sig 12 infsig Operación Push void push(NODEPTR * apunta, int x) { NODEPTR p = creaNodo(); p->info = x; if (estaVacia(*apunta)) { (*apunta) = p; } else { p->sig = (*apunta)->sig; } (*apunta)->sig = p; } Último nodo apunta P 6 inf sig 3 inf sig 12 infsig apunta PUSH

23 Listas Circulares: Pilas 6 inf sig 3 inf sig 8 inf sig 12 infsig Operación Pop int pop(NODEPTR * apunta) { if (estaVacia(*apunta)) { cout << Pila vacia!" << endl;exit(1); } NODEPTR p = (*apunta)->sig; int x = p->info; if (p == (*apunta)) (*apunta) = NULL; else (*apunta)->sig = p->sig; liberaNodo(p); return x; } Último Nodo Insertado apunta

24 Listas Circulares 6 inf sig 3 inf sig 8 inf sig 12 infsig Operación Traversal void traversaPila(NODEPTR apunta) { NODEPTR p = apunta; NODEPTR q, ultimo; if (!estaVacia(apunta)) { ultimo = q = p->sig; cout info << endl; q = q->sig; while (q != ultimo) { cout info << endl; q = q->sig; } Último Nodo Insertado apunta Primer Nodo Insertado

25 Listas Doblemente Vinculadas Aunque las listas circulares tienen ventajas sobre las listas lineales, todavía tienen algunas limitaciones importantes: No se puede recorrer la lista hacia atrás No puede suprimirse un nodo dado solo un apuntador hacia dicho nodo En una lista doblemente vinculada, cada nodo posee dos apuntadores, uno a su antecesor y otro a su sucesor Pueden ser lineales o circulares, y pueden o no tener un nodo de encabezado

26 Ejemplos de Listas Doblemente Vinculadas infsig Null12 prev infsig 14 prev infsig 10Null prev Lista doblemente vinculada infsig 12 prev infsig 14 prev infsig 10 prev Lista circular doblemente vinculada sin encabezado infsig 12 prev infsig 14 prev infsig 10 prev Lista circular doblemente vinculada con encabezado infsig prev

27 Definición: struct nodod{ int info; struct nodod *prev, *sig; }; typedef struct nodod * NODODOBLEPTR; Implementación de Listas Doblemente Vinculadas infsig prev

28 Implementación de Listas Doblemente Vinculadas Borra el nodo dado: int deleteNodoListaDoble(NODODOBLEPTR p){ if((p)==NULL){ cout<<"Error en borrado!"<info; l = p->prev; r = p->sig; if(l!=NULL) l->sig = r; if(r!=NULL) r->prev = l; free(p); return x; } infsig Null12 prev infsig 14 prev infsig 10Null prev

29 void insertaNodoDerecha(NODODOBLEPTR p, int x){ if(p==NULL){ cout<<"Error en insercion!"<info = x; r = p->sig; if(r!=NULL){ r->prev = q; } q->sig = r; q->prev = p; p->sig = q; } Implementación de Listas Doblemente Vinculadas


Descargar ppt "Estructura de Datos En C++ Dr. Romeo Sánchez Nigenda. Oficina: 1er. Piso del CIDET. Oficina."

Presentaciones similares


Anuncios Google