Programación Unidad 8 Resumen Teórico Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN1 1 Asignación Dinámica de Memoria (1) • La memoria dinámica es una zona de memoria perteneciente al programa, distinta de la memoria de datos, en donde se almacenan las variables dinámicas: aquellas que pueden crearse reservando la memoria necesaria en forma dinámica (en tiempo de ejecución) y cuando ya no sean útiles, eliminarlas liberando dicho espacio para que pueda ser utilizado por el programa. La gestión de la memoria dinámica se realiza básicamente con dos funciones que se encuentran en el archivo stdlib.h: Reservar: void * malloc(int); Liberar: void * free(void *); Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 2 Asignación Dinámica de Memoria (2) • void * malloc(int): Esta función recibe como parámetro el tamaño en bytes del bloque de memoria que se quiere reservar. La función se encarga de buscar una zona de memoria contigua del tamaño que se quiere reservar. Si la encuentra, devuelve la dirección de memoria de la celda inicial. Dicha dirección se devuelve como un puntero genérico (de tipo void *). En caso de no encontrar suficiente memoria para satisfacer la petición, la función devolverá el valor NULL. Por ejemplo: struct Registro * puntero; puntero = malloc(sizeof(struct Registro)); Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 3 Asignación Dinámica de Memoria (3) • void * free(void *): Esta función requiere como parámetro la dirección inicial de una zona de memoria dinámica reservada previamente. Esta dirección debe ser tal y como la suministró la función malloc. La función free se encarga de marcar como libre dicha zona de memoria, y de incorporarla al resto de la memoria dinámica. Si el parámetro es una dirección de memoria que no ha sido reservada previamente por malloc, los resultados son impredecibles. Por ejemplo: free(puntero); Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 4 Estructuras Dinámicas de Datos • Son aquellas estructuras cuyo tamaño (dado en longitud ó en número de elementos) varía en tiempo de ejecución. Se clasifican en: Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 5 Estructuras Dinámicas Lineales • Las operaciones básicas que se pueden realizar en las estructuras dinámicas lineales son las siguientes: 1) Recorrer: Procesar cada elemento de la estructura. 2) Búscar: Recuperar específico. la posición de un elemento 3) Agregar: Insertar un nuevo elemento a la estructura. 4) Eliminar: Borrar un elemento de la estructura. 5) Ordenar: Ordenamiento de los elementos de la estructura, de acuerdo a los valores que contiene. 6) Mezclar: Combinar dos estructuras en una sola. Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 6 Listas Enlazadas con Punteros (1) • Una lista enlazada es una colección lineal de elementos de cualquier tipo denominados nodos, que durante la ejecución del programa va creciendo ó decreciendo en cantidad de elementos, según las necesidades. • En una lista lineal el orden de los elementos se establece haciendo que cada elemento apunte al siguiente elemento, es decir que cada elemento tiene información de dónde se encuentra el siguiente elemento, de ahí el nombre de lista enlazada. • Existe un puntero especial llamado inicio, que contiene la dirección del primer elemento de la lista. Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 7 Listas Enlazadas con Punteros (2) • Cada nodo de la lista es un registro con al menos dos componentes, la primera almacena el dato genérico (de cualquier tipo) y la segunda es un puntero para poder señalar al siguiente elemento (tendrá el valor NULL si es el último elemento). Por ejemplo, una lista de números enteros tiene la siguiente forma: Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 8 Listas Enlazadas con Punteros (3) • Algunas de las operaciones que podemos realizar con listas son las siguientes: Inicializar: Hacer que la lista no contenga elementos. esVacía: Indicar si la lista contiene o no elementos. Insertar: Agregar un elemento a la lista. Eliminar: Sacar un elemento de la lista. Buscar: Buscar un elemento en la lista. Recorrer: Visitar todos los elementos de la lista. Largo: Determinar el número de elementos de la lista. Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 9 Listas Enlazadas con Punteros (4) • Para poder implementar las operaciones que podemos hacer con una lista, realizaremos primeramente las siguientes declaraciones: struct nodo{ int dato; struct nodo *sgte; }; typedef struct nodo tipoNodo; typedef tipoNodo *ptrNodo; Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 10 Listas Enlazadas con Punteros (5) • Inicializar: Como función y como procedimiento, respectivamente. ptrNodo Inicializar(void){ return(NULL); } void Inicializar(ptrNodo *inicio){ *inicio = NULL; } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 11 Listas Enlazadas con Punteros (6) • esVacía: Devuelve Verdadero (1) si la lista está vacía, en caso contrario devuelve Falso (0). int esVacia(ptrNodo inicio){ if (inicio != NULL) return (0); else return (1); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 12 Listas Enlazadas con Punteros (7) • Agregar (1): tipoNodo *p; p = malloc(sizeof(tipoNodo)); Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 13 Listas Enlazadas con Punteros (8) • Agregar (2): p -> dato = x; // x = 5 p -> sgte = inicio; Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 14 Listas Enlazadas con Punteros (9) • Agregar (3): inicio = p; Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 15 Listas Enlazadas con Punteros (10) • Agregar (4): Como función. ptrNodo Agregar(int x, ptrNodo inicio){ ptrNodo p; p = (ptrNodo) malloc(sizeof(tipoNodo)); p -> dato = x; // x = 5 p -> sgte = inicio; inicio = p; return(inicio); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 16 Listas Enlazadas con Punteros (11) • Agregar (5): Como procedimiento. void Agregar(int x, ptrNodo *inicio){ ptrNodo p; p = (ptrNodo) malloc(sizeof(tipoNodo)); p -> dato = x; // x = 5 p -> sgte = inicio; *inicio = p; } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 17 Listas Enlazadas con Punteros (12) • Mostrar: void Mostrar(tipoLista inicio){ ptrNodo p; p = inicio; while (p != NULL){ printf("%i", p -> dato); p = p -> sgte; } } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 18 Listas Enlazadas con Punteros (13) • Buscar: ptrNodo Buscar(int x, ptrNodo inicio){ ptrNodo p; p = inicio; while (p != NULL){ if (p -> dato == x) return(p); else p = p -> sgte; } } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 19 Listas Enlazadas con Punteros (14) • Eliminar (1): p = inicio; q = NULL; Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 20 Listas Enlazadas con Punteros (15) • Eliminar (2): while(p != NULL) && (!band){ band = (p -> dato == x); if (!band){q = p; p = p -> sgte;} } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 21 Listas Enlazadas con Punteros (16) • Eliminar (3): q -> sgte = p -> sgte; Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 22 Listas Enlazadas con Punteros (17) • Eliminar (4): free(p); Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 23 Listas Enlazadas con Punteros (18) • Eliminar (5): No contempla eliminar el nodo inicio. void Eliminar(int x, ptrNodo *inicio){ ptrNodo p, q; int band = 0; p = *inicio; q = NULL; while((p != NULL) && (!band)){ band = (p -> dato == x); if (!band){q = p; p = p -> sgte;} } q -> sgte = p -> sgte; free(p); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 24 Listas Enlazadas con Punteros (19) • Largo: Devuelve la cantidad de elementos (nodos) que contiene una lista. int Largo(ptrNodo inicio){ ptrNodo p, int cant = 0; for (p = inicio; p != NULL; p = p -> sgte) { cant++; } return(cant); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 25 Listas Enlazadas con Punteros (20) main(){ // con funciones ptrNodo Lista = Inicializar(); Lista = Agregar(3,Lista); Lista = Agregar(9,Lista); Lista = Agregar(6,Lista); Mostrar(Lista); Lista = Agregar(5,Lista); Mostrar(Lista); Eliminar(9,Lista); Mostrar(Lista); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 26 Listas Enlazadas con Punteros (21) main(){ // con procedimientos ptrNodo Lista; Inicializar(&Lista), Agregar(3,&Lista); Agregar(9,&Lista); Agregar(6,&Lista); Mostrar(Lista); Agregar(5,&Lista); Mostrar(Lista); Eliminar(9,&Lista); Mostrar(Lista); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 27 Pilas con Punteros (1) • Una pila representa una estructura lineal de datos en que se puede agregar o quitar elementos únicamente por uno de los dos extremos. En consecuencia, los elementos de una pila se eliminan en el orden inverso al que se insertaron. Debido a está característica, se le conoce como estructura LIFO (Last Input, First Output). • Existen muchos casos prácticos en los que se utiliza la idea de pila, como por ejemplo: una pila de platos, de libros, etc. • Existe un puntero especial llamado cima, que contiene la dirección del primer elemento de la pila (el de más arriba). Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 28 Pilas con Punteros (2) • Otro ejemplo de utilización de una pila es la evaluación general de cualquier expresión matemática, para evitar tener que calcular el número de variables temporales que hacen falta. Por ejemplo, se la siguiente expresión: 3 + 4 * (8 – 2 * 5) • Entonces la pila contendrá sucesivamente, los valores: Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 29 Pilas con Punteros (3) • Algunas de las operaciones que podemos realizar con pilas son las siguientes: Inicializar: Hacer que la pila no contenga elementos. esVacía: Indicar si la pila contiene o no elementos. Poner (push): Agregar un elemento a la pila. Sacar (pop): Eliminar un elemento de la pila. Mostrar: Visitar todos los elementos de la pila. Buscar: Buscar un elemento en la pila. Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 30 Pilas con Punteros (4) • Al igual que las listas, a la pila la podemos representar como una sucesión de nodos, que son registro con al menos dos componentes, la primera almacena el dato genérico y la segunda es un puntero para poder señalar al siguiente elemento (tendrá el valor NULL si es el último elemento). Por ejemplo, una pila de números enteros tiene la siguiente forma: Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 31 Pilas con Punteros (5) • Para poder implementar las operaciones que podemos hacer con una pila, realizaremos primeramente las siguientes declaraciones: struct nodo{ int dato; struct nodo *sgte; }; typedef struct nodo tipoNodo; typedef tipoNodo *ptrNodo; Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 32 Pilas con Punteros (6) • Inicializar: Como función y como procedimiento, respectivamente. ptrNodo Inicializar(void){ return(NULL); } void Inicializar(ptrNodo *cima){ *cima = NULL; } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 33 Pilas con Punteros (7) • Vacía: Devuelve Verdadero (1) si la lista está vacía, en caso contrario devuelve Falso (0), int esVacia(ptrNodo cima){ if (cima != NULL) return (0); else return (1); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 34 Pilas con Punteros (8) • Poner (1): Como función. ptrNodo Poner(int x, ptrNodo cima){ ptrNodo p; p = (ptrNodo) malloc(sizeof(tipoNodo)); p -> dato = x; p -> sgte = cima; cima = p; return(cima); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 35 Pilas con Punteros (9) • Poner (2): Como procedimiento. void Poner(int x, ptrNodo *cima){ ptrNodo p; p = (ptrNodo) malloc(sizeof(tipoNodo)); p -> dato = x; p -> sgte = *cima; *cima = p; } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 36 Pilas con Punteros (10) • Sacar: int Sacar(ptrNodo *cima){ ptrNodo p; int elem; if (!esVacia(*cima)){ p = *cima; elem = p -> dato; *cima = p -> sgte; free(p); return (elem); } } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 37 Pilas con Punteros (11) main(){ // con procedimientos ptrNodo Pila; Inicializar(&Pila), Poner(3,&Pila); Poner(9,&Pila); Poner(6,&Pila); Mostrar(Pila); Poner(5,&Pila); Mostrar(Pila); printf("Elemento: %d", Sacar(&Pila)); Mostrar(Pila); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 38 Colas con Punteros (1) • Una cola es un tipo particular de lista enlazada, en la que sólo se pueden insertar nodos en uno de los extremos de la lista, y sólo se pueden eliminar nodos en el otro extremo. Además, como sucede con las pilas, las escrituras de datos son siempre inserciones de nodos, y las lecturas siempre eliminan el nodo leído. Este tipo de lista es conocida como lista FIFO (Last In, First Out), ya que el primero en entrar es el primero en salir. • Existen dos punteros especiales llamado inicio y final, que contienen la dirección del primer y último elemento de la cola, respectivamente. Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 39 Colas con Punteros (2) • Un ejemplo cotidiano es una cola para comprar, por ejemplo las entradas a un espectáculo. Los compradores que van llegando, se van ubicando al final de la cola, y sólo el primero de la cola puede comprar la entrada. Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 40 Colas con Punteros (3) • Para poder implementar las operaciones que podemos hacer con una cola, realizaremos primeramente las siguientes declaraciones: struct nodo{ int dato; struct nodo *sgte; }; typedef struct nodo tipoNodo; typedef tipoNodo *ptrNodo; Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 41 Colas con Punteros (4) • Para un menor manejo de los punteros inicio y final, los encapsularemos en una estructura de la siguiente manera: struct cola{ ptrNodo inicio; ptrNodo final; }; typedef struct cola tipoCola; Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 42 Colas con Punteros (5) • Inicializar: void Inicializar(tipoCola *Q){ (*Q).inicio = NULL; (*Q).final = NULL; } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 43 Colas con Punteros (6) • Vacía: Devuelve Verdadero (1) si la cola está vacía, en caso contrario devuelve Falso (0). int Vacia(tipoCola Q){ if (Q.inicio != NULL) return (0); else return (1); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 44 Colas con Punteros (7) • Agregar: Suponemos que la cola no está vacía. void Agregar(int x, tipoCola *Q){ ptrNodo p; p = (ptrNodo) malloc(sizeof(tipoNodo)); p -> dato = x; p -> sgte = NULL; (*Q).final -> sgte = p; (*Q).final = p; } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 45 Colas con Punteros (8) • Eliminar: int Eliminar(tipoCola *Q){ int x; ptrNodo p; if (!esVacia(*Q)){ p = (*Q).inicio; x = p -> dato; (*Q).inicio = p -> sgte; free(p); return(x); } } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 46 Colas con Punteros (9) • Mostrar: void Mostrar(tipoCola Q){ ptrNodo p; p = Q.inicio; while (p != NULL){ printf("%i", p -> dato); p = p -> sgte; } } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 47 Colas con Punteros (10) main(){ // con procedimientos tipoCola Cola; Inicializar(&Cola), Agregar(3,&Cola); Agregar(9,&Cola); Agregar(6,&Cola); Mostrar(Cola); Agregar(5,&Cola); Mostrar(Cola); printf("Elemento: %d", Eliminar(&Cola)); Mostrar(Cola); } Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Programación TÉCNICO UNIVERSITARIO EN PROGRAMACIÓN 48