-/* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=1 fo+=t tw=80:
+/* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t tw=80:
*
* Taller de Programación (75.42).
*
*/
#include "dllist.h"
+/* Para usar NULL, malloc() y free(). */
#include <stdlib.h>
-bool DLList_init(DLList* list) {
- list = (DLList*)malloc(sizeof(DLList));
+DLList* DLList_new(void) {
+ /* Aloco memoria para la lista. */
+ DLList* list = (DLList*)malloc(sizeof(DLList));
+ /* Si la obtuve, inicializo todo a NULL. */
if (list) {
- list->first = NULL;
- list->current = NULL;
- list->last = NULL;
+ list->first = NULL;
+ list->current = NULL;
+ list->last = NULL;
+ }
+ /* Devuelvo el nuevo puntero. */
+ return list;
+}
+
+void DLList_delete(DLList* list) {
+ /* Si el puntero a la lista no es NULL. */
+ if (list) {
+ /* Elimino los nodos. */
+ while (!DLList_empty(list)) {
+ DLList_pop(list);
+ }
}
- return list ? TRUE : FALSE;
+ /* Libero memoria de la lista. */
+ free(list);
}
bool DLList_empty(DLList* list) {
return list->first == NULL;
}
-void* DLList_reset(DLList* list) {
+void* DLList_begin(DLList* list) {
list->current = list->first;
+ /* Si hay un nodo, devulevo sus datos, si no NULL. */
return list->current ? list->current->data : NULL;
}
+void* DLList_end(DLList* list) {
+ list->current = list->last;
+ /* Si hay un nodo, devulevo sus datos, si no NULL. */
+ return list->current ? list->current->data : NULL;
+}
+
+bool DLList_have_more(DLList* list) {
+ return list->current != NULL;
+}
+
void* DLList_current(DLList* list) {
return list->current ? list->current->data : NULL;
}
void* DLList_next(DLList* list) {
- DLNode* ret;
- ret = list->current;
- if (ret) {
- list->current = ret->next;
+ DLNode* current = list->current;
+ /* Si no está vacía ni ya fue terminada de recorrer. */
+ if (current) {
+ /* Apuntamos el actual al próximo. */
+ list->current = current->next;
+ /* Devolvemos los datos del próximo o NULL si no había otro. */
+ return list->current ? list->current->data : NULL;
+ /* Si está vacía o ya fue terminada de recorrer devolvemos NULL. */
+ } else {
+ return NULL;
+ }
+}
+
+void* DLList_prev(DLList* list) {
+ DLNode* current = list->current;
+ /* Si no está vacía ni ya fue terminada de recorrer. */
+ if (current) {
+ /* Apuntamos el actual al anterior. */
+ list->current = current->prev;
+ /* Devolvemos los datos del anterior o NULL si no había otro. */
return list->current ? list->current->data : NULL;
+ /* Si está vacía o ya fue terminada de recorrer devolvemos NULL. */
+ } else {
+ return NULL;
}
- return NULL;
}
bool DLList_unshift(DLList* list, void* data) {
node->prev = NULL;
node->data = data;
node->next = list->first;
+ /* Apunto el nodo actual al nuevo nodo. */
+ list->current = node;
/* Si la lista está vacía hay que hacer apuntar todo al nuevo nodo. */
- if (DLList_empty(list)) {
- list->first = node;
- list->current = node;
- list->last = node;
+ if (list->first == NULL) {
+ list->first = node;
+ list->last = node;
/* Si no está vacía. */
} else {
/* Apunto el nodo anterior al primer nodo de la lista al nuevo. */
node->prev = list->last;
node->data = data;
node->next = NULL;
+ /* Apunto el nodo actual al nuevo nodo. */
+ list->current = node;
/* Si la lista está vacía hay que hacer apuntar todo al nuevo nodo. */
- if (DLList_empty(list)) {
- list->first = node;
- list->current = node;
- list->last = node;
+ if (list->first == NULL) {
+ list->first = node;
+ list->last = node;
/* Si no está vacía. */
} else {
/* Apunto el próximo nodo del último nodo de la lista al nuevo. */
void* data = node->data;
/* Pongo como primer nodo al siguiente. */
list->first = node->next;
- /* Si era el único actualizo los otros punteros. */
+ /* Pongo al primero como nodo actual. */
+ list->current = list->first;
+ /* Si era el único pongo el último en NULL. */
if (!list->first) {
- list->last = NULL;
- list->current = NULL;
+ list->last = NULL;
+ /* Si no, pongo el anterior en NULL. */
+ } else {
+ list->first->prev = NULL;
}
/* Libero memoria del nodo. */
free(node);
void* data = node->data;
/* Pongo como último nodo al anterior. */
list->last = node->prev;
- /* Si era el único actualizo los otros punteros. */
+ /* Pongo al último como nodo actual. */
+ list->current = list->last;
+ /* Si era el único pongo el primero en NULL. */
if (!list->last) {
- list->first = NULL;
- list->current = NULL;
+ list->first = NULL;
+ /* Si no, pongo el siguiente en NULL. */
+ } else {
+ list->last->next = NULL;
}
/* Libero memoria del nodo. */
free(node);
return data;
}
+void* DLList_remove_current(DLList* list) {
+ /* Nodo actual */
+ DLNode* current = list->current;
+ /* Datos del nodo actual. */
+ void* data = current->data;
+ /* Si tiene siguiente. */
+ if (current->next) {
+ /* Se pone como anterior del siguiente al anterior del actual. */
+ current->next->prev = current->prev;
+ /* Si no tiene siguiente, se pone como último al anterior del actual. */
+ } else {
+ list->last = current->prev;
+ }
+ /* Si tiene anterior. */
+ if (current->prev) {
+ /* Se pone como siguiente del anterior al siguiente del actual. */
+ current->prev->next = current->next;
+ /* Si no tiene anterior, se pone como primero al siguiente del actual. */
+ } else {
+ list->first = current->next;
+ }
+ /* Pongo como elemento actual al próximo elemento. */
+ list->current = current->next;
+ /* Libero memoria del nodo. */
+ free(current);
+ return data;
+}
+