X-Git-Url: https://git.llucax.com/z.facultad/75.42/calculadora.git/blobdiff_plain/f74ef52ac13755f7680dbad22168b8d8e8b98e63..0030baf01844749eb88b276c6e8ce417cdd6914d:/dllist.c diff --git a/dllist.c b/dllist.c index ed2b62c..8b427dc 100644 --- a/dllist.c +++ b/dllist.c @@ -1,4 +1,4 @@ -/* 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). * @@ -15,39 +15,84 @@ */ #include "dllist.h" +/* Para usar NULL, malloc() y free(). */ #include -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) { @@ -58,11 +103,12 @@ 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. */ @@ -82,11 +128,12 @@ bool DLList_push(DLList* list, void* data) { 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. */ @@ -105,10 +152,14 @@ void* DLList_shift(DLList* list) { 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); @@ -122,13 +173,45 @@ void* DLList_pop(DLList* list) { 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; +} +