-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpila.c
117 lines (105 loc) · 3.86 KB
/
pila.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "pila.h"
#include <stdlib.h>
/* Definición del struct pila proporcionado por la cátedra.*/
#define CAPACIDAD_INICAL 32
#define DISMINUIR false
#define EXPANDIR true
struct pila {
void** datos;
size_t cantidad; // Cantidad de elementos almacenados.
size_t capacidad; // Capacidad del arreglo 'datos'.
};
/*******************************************************************
* PRIMITIVAS DE LA PILA *
*******************************************************************/
// Crea una pila.
// Post: devuelve una nueva pila vacía.
pila_t* pila_crear(void) {
pila_t* pila = malloc(sizeof(pila_t));
if (pila == NULL) return NULL;
pila->capacidad = CAPACIDAD_INICAL;
pila->cantidad = 0;
pila->datos = malloc((pila->capacidad) * sizeof(void*));
if (pila->datos == NULL) {
free(pila->datos);
return NULL;
}
return pila;
}
// Destruye la pila.
// Pre: la pila fue creada.
// Post: se eliminaron todos los elementos de la pila.
void pila_destruir(pila_t* pila) {
if (pila) {
free(pila->datos);
free(pila);
}
}
// Devuelve verdadero si la pila no tiene elementos apilados, false en caso
// contrario. Pre: la pila fue creada.
bool pila_esta_vacia(const pila_t* pila) { return (pila->cantidad == 0); }
// Obtiene el valor del tope de la pila. Si la pila tiene elementos,
// se devuelve el valor del tope. Si está vacía devuelve NULL.
// Pre: la pila fue creada.
// Post: se devolvió el valor del tope de la pila, cuando la pila no está
// vacía, NULL en caso contrario.
void* pila_ver_tope(const pila_t* pila) {
return (pila->cantidad == 0) ? NULL : (pila->datos[(pila->cantidad) - 1]);
}
// Redimensiona la pila en caso de ser necesario. Devuelve false de el realloc
// devuleva NULL. En caso contrario se sobrescriben los datos de la pila con la
// redimensión efenctuada.
// Pre: la pila fue creada, y en caso de que se la quiera agrandar el segundo
// parámetro debe ser "EXPANDIR", "DISMINUIR" en caso contrario.
// Post: en caso de que ocurra un error en el realloc, se mantienen los datos
// y la capacidad intactos y se devuelve false; si no ocurre ningún error se
// sobrescriben los datos y se devuelve true.
static bool redimensionar1(pila_t* pila, bool ajuste) {
pila->capacidad =
(ajuste == EXPANDIR) ? pila->capacidad << 1 : pila->capacidad / 2;
void** data_aux = realloc(pila->datos, pila->capacidad * sizeof(void*));
if (data_aux == NULL && ajuste == EXPANDIR) {
pila->capacidad = pila->capacidad >> 1;
return false;
}
if (data_aux == NULL && ajuste == DISMINUIR) {
pila->capacidad = pila->capacidad << 1;
return false;
}
pila->datos = data_aux;
return true;
}
// Agrega un nuevo elemento a la pila. Devuelve falso en caso de error.
// Pre: la pila fue creada.
// Post: se agregó un nuevo elemento a la pila, valor es el nuevo tope (si
// en algún momento el booleano que se devuleve se hace false, se devolverá
// true cuando se consiga realizar un realloc sin errores)
bool pila_apilar(pila_t* pila, void* valor) {
if (pila->capacidad == pila->cantidad) {
bool respuesta = redimensionar1(pila, 2);
if (respuesta == false) {
return false;
}
}
pila->datos[pila->cantidad] = valor;
pila->cantidad += 1;
return true;
}
// Saca el elemento tope de la pila. Si la pila tiene elementos, se quita el
// tope de la pila, y se devuelve ese valor. Si la pila está vacía, devuelve
// NULL.
// Pre: la pila fue creada.
// Post: si la pila no estaba vacía, se devuelve el valor del tope anterior
// y la pila contiene un elemento menos.
void* pila_desapilar(pila_t* pila) {
if (pila->cantidad == 0) {
return NULL;
}
if (pila->capacidad > pila->cantidad << 2 &&
(pila->capacidad >> 1) > CAPACIDAD_INICAL) {
redimensionar1(pila, DISMINUIR);
}
void* ultimo_elemento = pila->datos[(pila->cantidad) - 1];
pila->cantidad--;
return ultimo_elemento;
}