]> git.llucax.com Git - z.facultad/75.42/euler-oo.git/blob - dllist.cpp
Versiones preliminares de Dibujo y Figura.
[z.facultad/75.42/euler-oo.git] / dllist.cpp
1 /* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t tw=80:
2  *
3  * Taller de Programación (75.42).
4  *
5  * Ejercicio Número 2:
6  * Programa calculadora.
7  *
8  * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
9  * Puede copiar, modificar y distribuir este programa bajo los términos de
10  * la licencia GPL (http://www.gnu.org/).
11  *
12  * Creado: sáb ago 30 20:34:45 ART 2003
13  *
14  * $Id$
15  */
16
17 // TODO metodos que devuelven NULL si la lista esta vacia.
18 //      poner comentarios en línea simple?
19 #include "dllist.h"
20
21 DLList::DLList(void): first(NULL), current(NULL), last(NULL) {}
22
23 DLList::~DLList(void) {
24     /* Elimino los nodos. */
25     while (!DLList_empty(list)) {
26         DLList_pop(list);
27     }
28 }
29
30 bool DLList::empty(void) {
31     return this->first == NULL;
32 }
33
34 void* DLList::begin(void) {
35     this->current = this->first;
36     /* Si hay un nodo, devulevo sus datos, si no NULL. */
37     return this->current ? this->current->data : NULL;
38 }
39
40 void* DLList::end(void) {
41     this->current = this->last;
42     /* Si hay un nodo, devulevo sus datos, si no NULL. */
43     return this->current ? this->current->data : NULL;
44 }
45
46 bool DLList::have_more(void) {
47     return this->current != NULL;
48 }
49
50 void* DLList::current(void) {
51     return this->current ? this->current->data : NULL;
52 }
53
54 void* DLList::next(void) {
55     DLListNode* cur = this->current;
56     /* Si no está vacía ni ya fue terminada de recorrer. */
57     if (cur) {
58         /* Apuntamos el actual al próximo. */
59         this->current = cur->next;
60         /* Devolvemos los datos del próximo o NULL si no había otro. */
61         return this->current ? this->current->data : NULL;
62     /* Si está vacía o ya fue terminada de recorrer devolvemos NULL. */
63     } else {
64         return NULL;
65     }
66 }
67
68 void* DLList::prev(void) {
69     DLListNode* cur = this->current;
70     /* Si no está vacía ni ya fue terminada de recorrer. */
71     if (cur) {
72         /* Apuntamos el actual al anterior. */
73         this->current = cur->prev;
74         /* Devolvemos los datos del anterior o NULL si no había otro. */
75         return this->current ? this->current->data : NULL;
76     /* Si está vacía o ya fue terminada de recorrer devolvemos NULL. */
77     } else {
78         return NULL;
79     }
80 }
81
82 bool DLList::unshift(void* data) {
83     DLListNode* node = new DLListNode(NULL, data, this->first);
84     /* Si obtenemos la memoria bien, actualizamos lo que sea necesario. */
85     if (node) {
86         /* Apunto el nodo actual al nuevo nodo. */
87         this->current = node;
88         /* Si la lista está vacía hay que hacer apuntar todo al nuevo nodo. */
89         if (this->first == NULL) {
90             this->first = node;
91             this->last  = node;
92         /* Si no está vacía. */
93         } else {
94             /* Apunto el nodo anterior al primer nodo de la lista al nuevo. */
95             this->first->prev = node;
96             /* Apunto el primer nodo de la lista al nuevo. */
97             this->first = node;
98         }
99         return true;
100     } else {
101         return false;
102     }
103 }
104
105 bool DLList::push(void* data) {
106     DLListNode* node = new DLListNode(this->last, data, NULL);
107     /* Si obtenemos la memoria bien, actualizamos lo que sea necesario. */
108     if (node) {
109         /* Apunto el nodo actual al nuevo nodo. */
110         this->current = node;
111         /* Si la lista está vacía hay que hacer apuntar todo al nuevo nodo. */
112         if (this->first == NULL) {
113             this->first = node;
114             this->last  = node;
115         /* Si no está vacía. */
116         } else {
117             /* Apunto el próximo nodo del último nodo de la lista al nuevo. */
118             this->last->next = node;
119             /* Apunto el último nodo de la lista al nuevo. */
120             this->last = node;
121         }
122         return true;
123     } else {
124         return false;
125     }
126 }
127
128 void* DLList::shift(void) {
129     /* Primer nodo */
130     DLListNode* node = this->first;
131     /* Datos del primer nodo. */
132     void* data = node->data;
133     /* Pongo como primer nodo al siguiente. */
134     this->first = node->next;
135     /* Pongo al primero como nodo actual. */
136     this->current = this->first;
137     /* Si era el único pongo el último en NULL. */
138     if (!this->first) {
139         this->last = NULL;
140     /* Si no, pongo el anterior en NULL. */
141     } else {
142         this->first->prev = NULL;
143     }
144     /* Libero memoria del nodo. */
145     delete node;
146     return data;
147 }
148
149 void* DLList::pop(void) {
150     /* Último nodo */
151     DLListNode* node = this->last;
152     /* Datos del último nodo. */
153     void* data = node->data;
154     /* Pongo como último nodo al anterior. */
155     this->last = node->prev;
156     /* Pongo al último como nodo actual. */
157     this->current = this->last;
158     /* Si era el único pongo el primero en NULL. */
159     if (!this->last) {
160         this->first = NULL;
161     /* Si no, pongo el siguiente en NULL. */
162     } else {
163         this->last->next = NULL;
164     }
165     /* Libero memoria del nodo. */
166     delete node;
167     return data;
168 }
169
170 void* DLList::remove_current(void) {
171     /* Nodo actual */
172     DLListNode* current = this->current;
173     /* Datos del nodo actual. */
174     void* data = current->data;
175     /* Si tiene siguiente. */
176     if (current->next) {
177         /* Se pone como anterior del siguiente al anterior del actual. */
178         current->next->prev = current->prev;
179     /* Si no tiene siguiente, se pone como último al anterior del actual. */
180     } else {
181         this->last = current->prev;
182     }
183     /* Si tiene anterior. */
184     if (current->prev) {
185         /* Se pone como siguiente del anterior al siguiente del actual. */
186         current->prev->next = current->next;
187     /* Si no tiene anterior, se pone como primero al siguiente del actual. */
188     } else {
189         this->first = current->next;
190     }
191     /* Pongo como elemento actual al próximo elemento. */
192     this->current = current->next;
193     /* Libero memoria del nodo. */
194     delete current;
195     return data;
196 }
197