]> git.llucax.com Git - z.facultad/75.42/calculadora.git/blobdiff - dllist.c
Últimos retoques.
[z.facultad/75.42/calculadora.git] / dllist.c
index ed2b62ca385dc3e3f6d0805f6879d4dd42cf1dba..8b427dcb2724653c5c8d1792ca43f2f77c7b234a 100644 (file)
--- 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).
  *
  */
 
 #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) {
@@ -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;
+}
+