390 likes | 604 Views
Memoria Dinámica. Estructura de Datos. Concepto de estructura. Una estructura es un conjunto de una o m á s variables, de distinto tipo , agrupadas bajo un mismo nombre para que su manejo sea m á s sencillo.
E N D
Memoria Dinámica Estructura de Datos
Concepto de estructura • Una estructuraes un conjunto de una o más variables, de distinto tipo, agrupadas bajo un mismo nombre para que su manejo sea más sencillo. • Su utilización más habitual es para la programación de bases de datos, ya que están especialmente indicadas para el trabajo con registros o fichas.
Ejemplo de estructura struct trabajador { char nombre[20]; int matricula; }; Nombre matricula Esto es una estructura de tipo trabajador. (un nodo)
Nombre matricula *ptr Ejemplo de estructura con memoria dinámica (apuntadores) struct trabajador { char nombre[20]; int matricula; struct trabajador * ptr; }; Se le agrega un campo final del tipo apuntador a la misma estructura de donde proviene. Esto es una estructura de tipo trabajador. (un nodo)
Recorrido para visualizar o mostrar una estructura por valor (osea trabajando variables) void visualizar(struct trabajador datos) { printf("Nombre:%s",datos.nombre); printf("\nApellidos:%s",datos.apellidos); printf("\nEdad: %d",datos.edad); printf("\nPuesto: %s",datos.puesto); } Recibe una variable datos de tipo estructura y se maneja los campos con “.” punto
Recorrido para visualizar o mostrar una estructura por referencia (osea trabajando apuntadores) void visualizar(struct trabajador *datos) { printf("Nombre: %s",datos->nombre); printf("\nApellidos: %s",datos->apellidos); printf("\nEdad: %d",datos->edad); printf("\nPuesto: %s",datos->puesto); } Puntos importantes a checar: • En el parametro entra ahora un puntero • Al manejar el campo de cada registro no se usa el “.” PUNTO sino una -> FLECHA
Como se declara un apuntador a estructura? • Recuerdas como declarar un apuntador? • Recuerdas que requiere especificar a que tipo de dato apunta? • Ej. • Int *a; • Char *s1; El asterisco indica que no es una variable comun sino Que es una variable apuntadora, y lo que esta a la izq. Indica el tipo de dato a apuntar. Entonces esto es un apuntador a un entero Aquí estamos declarando un apuntador a un dato char Entonces Como se declara un apuntador a estructura?, Primero recordaremos Estructura de datos…..
Entonces como declaramos apuntador a estructura? struct trabajador { char nombre[20]; int matricula; struct trabajador * ptr; }; NECESITO UN APUNTADOR A ESTA ESTRUCTURA!!!! Sintaxis: Tipo estructura puntero Como declaramos ese tipo estructura?
Como se declara un tipo estructura? Typedef struct nuevonodo { Int matricula; Struct nuevonodo *siguiente } alumno; Entonces aquí decimos que alumno es el nuevo tipo de dato de tipo nuevonodo y podemos decir entonces: Alumno*ptr; aquí decimos que *ptr es puntero a un nodo de la estructura.
REFLEXIONEMOS… • Ya se como se declara una estructura para manejarse por referencia, osea con memoria dinamica. • Ya se como se accesan los campos haciendo uso de los apuntadores. • Ya se declarar un tipo de dato de la estructura • Ya se declarar un apuntador a una estructura. • Pero… • Como voy creando los nodos (un cuadrito de estructura) con memoria dinamica?
Malloc • Malloc: Se utiliza para la asignación dinámica de bloques de memoria solicitados de acuerdo a los parámetros enviados. Como parámetro se le envía el tamaño del dato para poder reservar la suficiente memoria. Esta función regresará la dirección de memoria asignada a la estructura solicitada • Para utilizar esta función es necesario hacer uso de la librería stdlib.h • Sintaxis: Ptr=malloc(size(alumno)) EL PUNTERO ptr ESTA APUNTANDO A LA DIRECCION DE MEMORIA DONDE SE RESERVÓ EL TAMAÑO DE LA ESTRUCTURA
#include <conio.h>#include <stdio.h>#include <stdlib.h>/* Para utilizar malloc*/ typedef struct _nodo{ int matricula; struct _nodo *siguiente;} alumno; Matrícula * siguiente Se esta decrarando un tipo de estructura “alumno” con la estructura _nodo que contiene 2 campos: matricula y *siguiente
#include <conio.h>#include <stdio.h>#include <stdlib.h>/* Para utilizar malloc*/typedef struct _nodo{ int matricula; struct _nodo *siguiente;} alumno;typedef alumno *pNodo;typedef alumno *Lista; Apuntador *pNodo, *Lista a estructura alumno Matrícula * siguiente
void main() { int i,n; clrscr(); printf("\n probando listas"); getch(); Lista lista=NULL; pNodo p; for (i=0;i<4;i++) { printf("\n dame la matricula del alumno %d",i+1); scanf("%d",&n); insertar(&lista,n); } MostrarLista(lista); printf("\n dame la matricula que quieres borrar"); scanf("%d",&n); Borrar(&lista,n); MostrarLista(lista); getch(); } Se declara el apuntador lista del tipo Lista (tipo alumno) en Nulo (NULL) ya que apenas vamos a comenzar el proceso de creaciòn de listas. Recordar que NULL significa VACÎO
void main() { int i,n; clrscr(); printf("\n probando listas"); getch(); Lista lista=NULL; pNodo p; for (i=0;i<4;i++) { printf("\n dame la matricula del alumno %d",i+1); scanf("%d",&n); insertar(&lista,n); } MostrarLista(lista); printf("\n dame la matricula que quieres borrar"); scanf("%d",&n); Borrar(&lista,n); MostrarLista(lista); getch(); } Se declara el apuntador p del tipo pNodo (tipo alumno)
void main() { int i,n; clrscr(); printf("\n probando listas"); getch(); Lista lista=NULL; pNodo p; for (i=0;i<4;i++) { printf("\n dame la matricula del alumno %d",i+1); scanf("%d",&n); insertar(&lista,n); } MostrarLista(lista); printf("\n dame la matricula que quieres borrar"); scanf("%d",&n); Borrar(&lista,n); MostrarLista(lista); getch(); } Ciclo que inserta 4 matrículas dentro de la lista , la cual fue anteriormente inicializada en NULL.
void main() { int i,n; clrscr(); printf("\n probando listas"); getch(); Lista lista=NULL; pNodo p; for (i=0;i<4;i++) { printf("\n dame la matricula del alumno %d",i+1); scanf("%d",&n); insertar(&lista,n); } MostrarLista(lista); printf("\n dame la matricula que quieres borrar"); scanf("%d",&n); Borrar(&lista,n); MostrarLista(lista); getch(); } Se manda el control a la función insertar con parámetros (dirección inicial de la lista, y el valor de la matrícula a insertar).
Recibe del main los parámetros de el contenido de la estructura de la lista y el valor que insertaremos=matrícula void insertar(Lista *lista, int v) { pNodo nuevo, anterior; nuevo=(pNodo)malloc(sizeof(alumno)); nuevo->matricula=v; if (*lista==NULL) { nuevo->siguiente=NULL; *lista=nuevo; } else { anterior=*lista; while(anterior->siguiente) anterior=anterior->siguiente; nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } }
void insertar(Lista *lista, int v) { pNodo nuevo, anterior; nuevo=(pNodo)malloc(sizeof(alumno)); nuevo->matricula=v; if (*lista==NULL) { nuevo->siguiente=NULL; *lista=nuevo; } else { anterior=*lista; while(anterior->siguiente) anterior=anterior->siguiente; nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } } Declaración de dos punteros nuevo y anterior a la estructura pNodo
void insertar(Lista *lista, int v) { pNodo nuevo, anterior; nuevo=(pNodo)malloc(sizeof(alumno)); nuevo->matricula=v; if (*lista==NULL) { nuevo->siguiente=NULL; *lista=nuevo; } else { anterior=*lista; while(anterior->siguiente) anterior=anterior->siguiente; nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } } Malloc-> funciòn que solicita un espacio en memoria del tamaño (sizeof) de la estructura alumno. Se asigna a nuevo un puntero de tipo pNodo a la dirección dada por malloc
void insertar(Lista *lista, int v) { pNodo nuevo, anterior; nuevo=(pNodo)malloc(sizeof(alumno)); nuevo->matricula=v; if (*lista==NULL) { nuevo->siguiente=NULL; *lista=nuevo; } else { anterior=*lista; while(anterior->siguiente) anterior=anterior->siguiente; nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } } En la estructura creada se asigna al elemento matrícula el valor v
void insertar(Lista *lista, int v) { pNodo nuevo, anterior; nuevo=(pNodo)malloc(sizeof(alumno)); nuevo->matricula=v; if (*lista==NULL) { nuevo->siguiente=NULL; *lista=nuevo; } else { anterior=*lista; while(anterior->siguiente) anterior=anterior->siguiente; nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } } Se verifica si la lista esta vacía (o sea NULL) para comenzar la lista o de lo contrario insertar el elemento al final de la lista
void insertar(Lista *lista, int v) { pNodo nuevo, anterior; nuevo=(pNodo)malloc(sizeof(alumno)); nuevo->matricula=v; if (*lista==NULL) { nuevo->siguiente=NULL; *lista=nuevo; } else { anterior=*lista; while(anterior->siguiente) anterior=anterior->siguiente; nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } } En el caso de que sí esta vacía al elemento apuntador siguiente de la estructura se le asigna NULL ya que es el primer elemento de la lista y se asigna a *listala dirección asignada por malloc
void insertar(Lista *lista, int v) { pNodo nuevo, anterior; nuevo=(pNodo)malloc(sizeof(alumno)); nuevo->matricula=v; if (*lista==NULL) { nuevo->siguiente=NULL; *lista=nuevo; } else { anterior=*lista; while(anterior->siguiente) anterior=anterior->siguiente; nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } } En el caso de que sí esta vacía al elemento apuntador siguiente de la estructura se le asigna NULL ya que es el primer elemento de la lista y se asigna a *listala dirección asignada por malloc De lo contrario (ya hay elementos en la lista) se dá la dirección asignada por malloc al apuntador anterior . Se hace un ciclo donde se va recorriendo cada elemento hasta llegar al final de la lista y se asigna la dirección del nuevo elemento
void insertar(Lista *lista, int v) { pNodo nuevo, anterior; nuevo=(pNodo)malloc(sizeof(alumno)); nuevo->matricula=v; if (*lista==NULL) { nuevo->siguiente=NULL; *lista=nuevo; } else { anterior=*lista; while(anterior->siguiente) anterior=anterior->siguiente; nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } } Regresa el control al main ( )
void main() { int i,n; clrscr(); printf("\n probando listas"); getch(); Lista lista=NULL; pNodo p; for (i=0;i<4;i++) { printf("\n dame la matricula del alumno %d",i+1); scanf("%d",&n); insertar(&lista,n); } MostrarLista(lista); getch(); } Manda el control a la función que despliega los nodos de la lista
void MostrarLista(Lista lista) { pNodo nodo = lista; if(lista==NULL) printf("Lista vacía\n"); else { while(nodo!=NULL){ printf("%d ", nodo->matricula); nodo = nodo->siguiente; } printf("\n"); } } Del tipo pNodo crea un apuntador nodo y le asigna la dirección que le mandó como parámetro, la cual es el inicio de la lista
void MostrarLista(Lista lista) { pNodo nodo = lista; if(lista==NULL) printf("Lista vacía\n"); else { while(nodo!=NULL){ printf("%d ", nodo->matricula); nodo = nodo->siguiente; } printf("\n"); } } Si la lista esta vacía, imprime el mensaje “Lista vacía”
void MostrarLista(Lista lista) { pNodo nodo = lista; if(lista==NULL) printf("Lista vacía\n"); else { while(nodo!=NULL){ printf("%d ", nodo->matricula); nodo = nodo->siguiente; } printf("\n"); } } De lo contrario hace el ciclo mientras no se encuentre NULL, e imprime la matrícula de cada elemento. Se asigna la dirección del siguiente elemento de la lista a nodo
void MostrarLista(Lista lista) { pNodo nodo = lista; if(lista==NULL) printf("Lista vacía\n"); else { while(nodo!=NULL){ printf("%d ", nodo->matricula); nodo = nodo->siguiente; } printf("\n"); } } Regresa el control al main ( )
Ejemplificación de la inserción de nodos Primer Nodo de la Lista Matrícula • Siguiente • NULL
Inserto otro nodo con la misma estructura Matrícula Matrícula • Siguiente • Siguiente • NULL
Inserto otro nodo con la misma estructura Matrícula Matrícula Matrícula • Siguiente • Siguiente • Siguiente • NULL
Inserto otro nodo con la misma estructura Matrícula Matrícula Matrícula Matrícula • Siguiente • Siguiente • Siguiente • Siguiente • NULL
Para Borrar un nodo • Guardo la dirección *siguiente del nodo que deseo eliminar • Asigno la dirección *siguiente del nodo que deseo eliminar al nodo anterior al que deseo eliminar Matrícula Matrícula Matrícula Matrícula • Siguiente • Siguiente • Siguiente • Siguiente • NULL
Para Borrar un nodo • Guardo la dirección *siguiente del nodo que deseo eliminar • Asigno la dirección *siguiente del nodo que deseo eliminar al nodo anterior al que deseo eliminar Matrícula Matrícula Matrícula Matrícula • Siguiente • Siguiente • Siguiente • Siguiente • NULL
Para Borrar un nodo • Guardo la dirección *siguiente del nodo que deseo eliminar • Asigno la dirección *siguiente del nodo que deseo eliminar al nodo anterior al que deseo eliminar Matrícula Matrícula Matrícula Matrícula • Siguiente • Siguiente • Siguiente • Siguiente • NULL
Para Borrar un nodo • Guardo la dirección *siguiente del nodo que deseo eliminar • Asigno la dirección *siguiente del nodo que deseo eliminar al nodo anterior al que deseo eliminar Matrícula Matrícula Matrícula Matrícula • Siguiente • Siguiente • Siguiente • Siguiente • NULL
Para Borrar un nodo • Guardo la dirección *siguiente del nodo que deseo eliminar • Asigno la dirección *siguiente del nodo que deseo eliminar al nodo anterior al que deseo eliminar Matrícula Matrícula Matrícula Matrícula • Siguiente • Siguiente • Siguiente • Siguiente • NULL