7 #define LT(b, x, y) (b->cmp(x, y) < 0)
8 #define GT(b, x, y) (b->cmp(x, y) > 0)
9 #define EQ(b, x, y) (b->cmp(x, y) == 0)
10 #define NE(b, x, y) (b->cmp(x, y) != 0)
11 #define LE(b, x, y) (b->cmp(x, y) <= 0)
12 #define GE(b, x, y) (b->cmp(x, y) >= 0)
14 static BUFFORD_NODE* bufford_node_new(void* data, size_t reg_size);
16 static void bufford_node_delete(BUFFORD_NODE* node);
18 static void bufford_clear_node_recursive(BUFFORD_NODE* node);
20 static void bufford_insert_node(BUFFORD* buff, BUFFORD_NODE* new_node);
22 BUFFORD_NODE* bufford_node_new(void* data, size_t reg_size)
24 BUFFORD_NODE* n = malloc(sizeof(BUFFORD_NODE));
27 /* hago una copia del dato */
28 n->data = malloc(reg_size);
30 memcpy(n->data, data, reg_size);
40 void bufford_node_delete(BUFFORD_NODE* node)
46 void bufford_clear_node_recursive(BUFFORD_NODE* node)
50 if (node->left) bufford_clear_node_recursive(node->left);
51 if (node->right) bufford_clear_node_recursive(node->right);
53 bufford_node_delete(node);
56 void bufford_insert_node(BUFFORD* buff, BUFFORD_NODE* new_node)
60 if (buff->root) { /* no está vacío */
61 BUFFORD_NODE* curr = buff->root;
64 if (LT(buff, new_node->data, curr->data)) {
65 if (curr->left) { /* hay más, paso al próximo */
69 /* no hay más, lo inserto */
70 curr->left = new_node;
73 if (GT(buff, new_node->data, curr->data)) {
74 if (curr->right) { /* hay más, paso al próximo */
78 /* no hay más, lo inserto */
79 curr->right = new_node;
82 /* es igual! => error */
83 assert(NE(buff, new_node->data, curr->data));
88 buff->root = new_node;
91 BUFFORD* bufford_new(size_t size, size_t reg_size, CMP_FUNC cmp)
93 BUFFORD* b = malloc(sizeof(BUFFORD));
97 assert(size > reg_size);
101 b->max_size = size / reg_size;
102 b->reg_size = reg_size;
106 void bufford_delete(BUFFORD* buff)
113 void bufford_clear(BUFFORD* buff)
116 if (buff->root) bufford_clear_node_recursive(buff->root);
120 int bufford_full(BUFFORD* buff)
123 return buff->size == buff->max_size;
126 int bufford_empty(BUFFORD* buff)
129 return buff->size == 0;
132 int bufford_push(BUFFORD* buff, void* data)
134 BUFFORD_NODE* new_node;
137 if (buff->size == buff->max_size) return 0; /* ERROR, está lleno */
138 new_node = bufford_node_new(data, buff->reg_size);
139 if (!new_node) return 0; /* ERROR, no hay memoria */
140 if (buff->root) { /* no está vacío */
141 BUFFORD_NODE* curr = buff->root;
144 if (LT(buff, data, curr->data)) {
145 if (curr->left) { /* hay más, paso al próximo */
149 /* no hay más, lo inserto */
150 curr->left = new_node;
154 if (GT(buff, data, curr->data)) {
155 if (curr->right) { /* hay más, paso al próximo */
159 /* no hay más, lo inserto */
160 curr->right = new_node;
164 /* es igual! => error */
166 assert(NE(buff, data, curr->data));
167 return 0; /* ERROR, dato duplicado */
171 buff->root = new_node;
176 void* bufford_pop(BUFFORD* buff, void* min)
179 BUFFORD_NODE* curr = buff->root;
180 /* nodo previo al iterador */
181 BUFFORD_NODE* prev = 0;
182 /* nodo con el dato más pequeño encontrado hasta ahora */
183 BUFFORD_NODE* curr_min = 0;
184 /* padre del nodo con el dato más pequeño encontrado hasta ahora */
185 BUFFORD_NODE* padre = 0;
186 /* valor mínimo encontrado, si se encontró */
190 /* buscamos el mínimo nodo mayor que 'min' */
192 if (GT(buff, curr->data, min)) { /* actual mayor que buscado */
193 /* guardo y paso al de la izquierda */
198 } else { /* actual no es mayor que buscado, paso a derecha */
203 /* si encontramos uno, lo sacamos del árbol */
205 BUFFORD_NODE* link; /* nodo al cual enganchar con el padre */
206 BUFFORD_NODE* orphan = 0; /* nodo huerfano */
207 if (curr_min->left) {
208 link = curr_min->left;
209 orphan = curr_min->right;
211 link = curr_min->right;
213 if (padre) { /* si tiene padre (no es el raíz) */
214 if (padre->left == curr_min) { /* si es el de la izq */
215 padre->left = link; /* enganchamos */
216 } else { /* si no, es el de la derecha */
217 padre->right = link; /* enganchamos */
219 } else { /* si es el raíz */
220 buff->root = link; /* ponemos el nuevo raíz */
222 if (orphan) { /* si quedó un huerfano, lo insertamos */
223 bufford_insert_node(buff, orphan);
225 min_found = curr_min->data;
226 bufford_node_delete(curr_min);
232 void* bufford_pop_min(BUFFORD* buff)
235 BUFFORD_NODE* curr = buff->root;
236 /* nodo previo al iterador */
237 BUFFORD_NODE* prev = 0;
238 /* valor mínimo encontrado, si se encontró */
241 if (!curr) return 0; /* si no hay nodos, no hay nada que hacer */
242 /* buscamos el mínimo nodo */
247 /* lo sacamos del árbol */
248 if (prev) { /* si tiene padre (no es el raíz) */
249 /* le cuelgo de la izquierda el hijo de la derecha, sabemos que a
250 * izquierda no tiene nada.*/
251 prev->left = curr->right;
252 } else { /* si es el raíz */
253 buff->root = curr->right; /* ponemos el nuevo raíz */
255 min_found = curr->data;
256 bufford_node_delete(curr);
261 void* bufford_get_min(BUFFORD* buff)
264 BUFFORD_NODE* curr = buff->root;
266 if (!curr) return 0; /* si no hay nodos, no hay nada que hacer */
267 /* buscamos el mínimo nodo */
268 while (curr->left) curr = curr->left;
272 void* bufford_get_next(BUFFORD* buff, void* min)
275 BUFFORD_NODE* curr = buff->root;
276 /* nodo con el dato más pequeño encontrado hasta ahora */
277 BUFFORD_NODE* curr_min = 0;
280 /* buscamos el mínimo nodo mayor que 'min' */
282 if (GT(buff, curr->data, min)) { /* actual mayor que buscado */
283 /* guardo y paso al de la izquierda */
286 } else curr = curr->right; /* paso a la derecha */
288 if (curr_min) return curr_min->data;