Programación en C: Implementación de Listas Enlazadas, Pilas y Gestión de Ficheros
Enviado por Programa Chuletas y clasificado en Informática y Telecomunicaciones
Escrito el en español con un tamaño de 11 KB
Conceptos de Recorrido (Árboles)
Estos términos se refieren comúnmente a los órdenes de recorrido en estructuras de datos tipo árbol:
- PreOrden (Raíz-Izquierda-Derecha): RID
- InOrden (Izquierda-Raíz-Derecha): IRD
- PostOrden (Izquierda-Derecha-Raíz): IDR
Lista Lineal Simplemente Enlazada en C
Este apartado presenta la implementación de una lista lineal simplemente enlazada en C, incluyendo funciones básicas para su gestión.
Declaraciones Globales y Estructura del Elemento
typedef struct s // Declaración del tipo struct, elemento de la cadena
{
int num1;
float num2;
struct s *siguiente;
} elemento;
elemento *lista = NULL; // Declaración del puntero maestro global
Prototipos de Funciones
void insertar(int x, float y);
void imprimir(void);
void borrar(void);
Función Principal (main)
main()
{
int x;
float y;
printf("Introduzca datos:\n");
while (1)
{
printf("x = ");
if (scanf("%d", &x) != 1) break;
printf("y = ");
if (scanf("%f", &y) != 1) break;
insertar(x, y);
}
printf("\nLos datos introducidos son:\n");
imprimir();
borrar();
}
Implementación de Funciones de la Lista
Insertar un Nuevo Elemento al Principio de la Lista
void insertar(int x, float y) // Introducir nuevo elemento al principio de la lista
{
elemento *q = (elemento *)malloc(sizeof(elemento));
if (q == NULL)
{
printf("Falta memoria");
// getch(); // getch() es específico de algunas librerías, se omite o se reemplaza si no es estándar.
}
else
{
q->num1 = x;
q->num2 = y;
q->siguiente = lista;
lista = q;
}
}
Mostrar Todos los Elementos de la Lista
void imprimir(void) // Escribir todos los elementos de la lista
{
elemento *q = lista;
while (q != NULL)
{
printf("x = %d, y = %g\n", q->num1, q->num2);
q = q->siguiente;
}
}
Eliminar Todos los Elementos de la Lista
void borrar(void) // Borrar todos los elementos de la lista
{
elemento *q = lista;
while (q != NULL)
{
lista = lista->siguiente;
free(q);
q = lista;
}
}
Inserción de Elementos Adicionales en la Lista
Insertar un Nuevo Elemento Después de uno Dado por el Puntero p
// Insertar un nuevo elemento después de uno dado por el puntero "p"
void insertarsig(elemento *p, int x, float y)
{
elemento *q = NuevoElemento();
if (q != NULL)
{
q->num1 = x;
q->num2 = y;
q->siguiente = p->siguiente;
p->siguiente = q;
}
}
Insertar un Nuevo Elemento Antes de uno Dado por el Puntero p
// Insertar un nuevo elemento antes de uno dado por el puntero "p"
void insertarant(elemento *p, int x, float y)
{
elemento *q = NuevoElemento();
if (q) // Equivalente a (q != NULL)
{
*q = *p;
p->num1 = x;
p->num2 = y;
p->siguiente = q;
}
}
Creación de un Nuevo Elemento de la Lista
// Crear nuevo elemento de la lista
elemento *NuevoElemento(void)
{
elemento *q = (elemento *)malloc(sizeof(elemento));
if (q == NULL)
{
printf("Falta memoria");
// getch(); // getch() es específico de algunas librerías, se omite o se reemplaza si no es estándar.
}
return q;
}
Eliminación de Elementos de la Lista
Eliminar un Elemento Dado (si no es el último de la lista)
// Eliminar un elemento dado, si no es el último de la lista
void eliminar(elemento *p)
{
elemento *q = p->siguiente;
if (q != NULL)
{
*p = *q;
free(q);
}
}
Eliminar el Elemento Siguiente a uno Dado
// Eliminar el elemento siguiente a uno dado
void eliminarsig(elemento *p)
{
elemento *q = p->siguiente;
if (q) // Equivalente a (q != NULL)
{
p->siguiente = q->siguiente;
free(q);
}
}
Búsqueda de Elementos en la Lista
Buscar un Elemento Específico en la Lista
// Buscar un elemento de la lista
void buscar(void)
{
int num;
elemento *q = lista;
printf("Ingrese el valor de X a buscar:");
if (scanf("%d", &num) != 1) return;
while (q != NULL && q->num1 != num) q = q->siguiente;
if (q == NULL) printf("Dato no encontrado.\n");
else printf("El valor de Y asociado a X=%d es: %g\n", num, q->num2);
}
Ejercicio: Función de Búsqueda en Lista Enlazada
La función fun
busca un elemento en una lista lineal enlazada, en la que cada elemento tiene el siguiente tipo de datos: typedef struct nodo
typedef struct nodo
{
int dato;
struct nodo *sig;
} lista;
El primer parámetro p
es un puntero al primer elemento de la lista y el segundo parámetro num
es el número que se busca. La función fun
ha de devolver la dirección del elemento de la lista, si encuentra el número a buscar, y devuelve NULL
si no se encuentra el número en la lista.
lista *fun(lista *p, int num)
{
int sw = 0;
/* Código a completar */
while ((p != NULL) && (sw == 0))
{
if (p->dato == num) sw = 1;
else p = p->sig;
}
if (sw) return (p);
else return NULL;
}
Ejercicio: Función para Suprimir Elemento de una Pila
La pila de la figura es controlada mediante el puntero de ámbito global pi
. El puntero pi
apunta al último elemento que se introdujo en la pila. Se quiere realizar una función llamada fun
, que permita suprimir un elemento de la pila y lo imprima.
/* Suponiendo la estructura de la pila y 'nom' y 'pt' declarados */
void fun_suprimir_pila(/* parámetros si los hubiera, o si 'pi' es global */)
{
/* Código a completar */
// Las líneas proporcionadas para completar la función son:
// strcpy(nom, pi->nombre); // 'nom' y 'pi->nombre' deben estar definidos
// printf("%s\n ", nom);
// pt = pi; // 'pt' debe estar definido
// pi = pi->sig;
// free(pt); // Se debería liberar la memoria del elemento suprimido
}
Las líneas proporcionadas para completar la función son:
strcpy(nom, pi->nombre);
printf("%s\n ", nom);
pt = pi;
pi = pi->sig;
Nota: Para una implementación completa, se necesitaría la definición de la estructura de la pila y las declaraciones de nom
(como un array de caracteres) y pt
(como un puntero del mismo tipo que pi
). Además, se debería liberar la memoria del elemento suprimido con free(pt)
.
Ejercicio: Modificación de Registro en Fichero
Suponiendo un fichero abierto para lectura y escritura y referenciado por pf
, que almacena estructuras de la forma: struct alumn { char nombre[40]; float nota; };
Indicar qué sentencias hay que sustituir por el comentario, para que la función fun
permita cambiar la nota, poniendo un 5.0 en el registro referenciado por el parámetro p
. La función devuelve el registro modificado.
struct alumn fun(FILE *pf, int p)
{
struct alumn a;
/* Código a completar */
fseek(pf, (long)p * sizeof(a), SEEK_SET); // Posicionar al inicio del registro 'p'
fread(&a, sizeof(a), 1, pf); // Leer el registro
a.nota = 5.0; // Modificar la nota
fseek(pf, (long)p * sizeof(a), SEEK_SET); // Volver a posicionar para escribir
fwrite(&a, sizeof(a), 1, pf); // Escribir el registro modificado
return (a);
}
Las líneas proporcionadas para completar la función son:
fseek(pf, (long)p * sizeof(a), 0); // 0 es SEEK_SET
fread(&a, sizeof(a), 1, pf);
a.nota = 5.0;
fseek(pf, (long)p * sizeof(a), 0); // 0 es SEEK_SET
fwrite(&a, sizeof(a), 1, pf);
Conceptos de Pila: Push y Pop
- Push: Operación para insertar un elemento en la pila.
- Pop: Operación para extraer un elemento de la pila.
Ejercicio: Intercambio de Registros en Fichero
Un fichero de estructuras llamado alumnos contiene estructuras del tipo struct alu
, y está abierto (en modo w+
) y apuntado por el puntero pf
. Indicar qué sentencias hay que sustituir por el comentario, para que la función fun
intercambie el primer registro del fichero por el último registro.
struct alu
{
char nombre[50];
double nota;
};
void fun(FILE *pf)
{
struct alu a, b;
int n_reg;
/* Código a completar */
fseek(pf, 0L, SEEK_END); // Mover al final del fichero
n_reg = (int)ftell(pf) / sizeof(struct alu); // Calcular número total de registros
fseek(pf, (long)0 * sizeof(struct alu), SEEK_SET); // Posicionar al primer registro
fread(&a, sizeof(struct alu), 1, pf); // Leer el primer registro
fseek(pf, (long)(n_reg - 1) * sizeof(struct alu), SEEK_SET); // Posicionar al último registro
fread(&b, sizeof(struct alu), 1, pf); // Leer el último registro
fseek(pf, (long)0 * sizeof(struct alu), SEEK_SET); // Volver a posicionar para escribir el primer registro
fwrite(&b, sizeof(struct alu), 1, pf); // Escribir el último registro en la posición del primero
fseek(pf, (long)(n_reg - 1) * sizeof(struct alu), SEEK_SET); // Volver a posicionar para escribir el último registro
fwrite(&a, sizeof(struct alu), 1, pf); // Escribir el primer registro en la posición del último
}
Las líneas proporcionadas para completar la función son:
fseek(pf, 0L, SEEK_END);
n_reg = (int)ftell(pf) / sizeof(struct alu);
fseek(pf, (long)0 * sizeof(struct alu), 0); // 0 es SEEK_SET
fread(&a, sizeof(struct alu), 1, pf);
fseek(pf, (long)(n_reg - 1) * sizeof(struct alu), 0); // 0 es SEEK_SET
fread(&b, sizeof(struct alu), 1, pf);
fseek(pf, (long)0 * sizeof(struct alu), 0); // 0 es SEEK_SET
fwrite(&b, sizeof(struct alu), 1, pf);
fseek(pf, (long)(n_reg - 1) * sizeof(struct alu), 0); // 0 es SEEK_SET
fwrite(&a, sizeof(struct alu), 1, pf);