]> git.llucax.com Git - z.facultad/75.42/euler-oo.git/blob - dllist.cpp
Se agrega el Círculo.
[z.facultad/75.42/euler-oo.git] / dllist.cpp
1 /* vim: set et sts=4 sw=4 fdm=indent fdn=1 fo+=t tw=80:
2  *
3  * Taller de Programación (75.42).
4  *
5  * Ejercicio Número 3:
6  * Lista de figuras.
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 #include "dllist.h"
18 #include <cstdlib>
19
20 #ifdef DEBUG
21 #   include <iostream>
22 #endif
23
24 DLList::DLList(void): first(NULL), curr(NULL), last(NULL) {
25 #ifdef DEBUG
26     std::cerr << "En constructor de DLList." << std::endl;
27 #endif
28 }
29
30 DLList::~DLList(void) {
31 #ifdef DEBUG
32     std::cerr << "En destructor de DLList." << std::endl;
33 #endif
34     /* Elimino los nodos. */
35     while (!empty()) {
36         pop();
37     }
38 }
39
40 bool DLList::empty(void) {
41     return first == NULL;
42 }
43
44 void* DLList::begin(void) {
45     curr = first;
46     /* Si hay un nodo, devulevo sus datos, si no NULL. */
47     return curr ? curr->data : NULL;
48 }
49
50 void* DLList::end(void) {
51     curr = last;
52     /* Si hay un nodo, devulevo sus datos, si no NULL. */
53     return curr ? curr->data : NULL;
54 }
55
56 bool DLList::have_more(void) {
57     return curr != NULL;
58 }
59
60 void* DLList::current(void) {
61     return curr ? curr->data : NULL;
62 }
63
64 void* DLList::next(void) {
65     DLListNode* new_curr = curr;
66     /* Si no está vacía ni ya fue terminada de recorrer. */
67     if (new_curr) {
68         /* Apuntamos el actual al próximo. */
69         curr = new_curr->next;
70         /* Devolvemos los datos del próximo o NULL si no había otro. */
71         return curr ? curr->data : NULL;
72     /* Si está vacía o ya fue terminada de recorrer devolvemos NULL. */
73     } else {
74         return NULL;
75     }
76 }
77
78 void* DLList::prev(void) {
79     DLListNode* new_curr = curr;
80     /* Si no está vacía ni ya fue terminada de recorrer. */
81     if (new_curr) {
82         /* Apuntamos el actual al anterior. */
83         curr = new_curr->prev;
84         /* Devolvemos los datos del anterior o NULL si no había otro. */
85         return curr ? curr->data : NULL;
86     /* Si está vacía o ya fue terminada de recorrer devolvemos NULL. */
87     } else {
88         return NULL;
89     }
90 }
91
92 bool DLList::unshift(void* data) {
93     DLListNode* node = new DLListNode(NULL, data, first);
94     /* Si obtenemos la memoria bien, actualizamos lo que sea necesario. */
95     if (node) {
96         /* Apunto el nodo actual al nuevo nodo. */
97         curr = node;
98         /* Si la lista está vacía hay que hacer apuntar todo al nuevo nodo. */
99         if (first == NULL) {
100             first = node;
101             last  = node;
102         /* Si no está vacía. */
103         } else {
104             /* Apunto el nodo anterior al primer nodo de la lista al nuevo. */
105             first->prev = node;
106             /* Apunto el primer nodo de la lista al nuevo. */
107             first = node;
108         }
109         return true;
110     } else {
111         return false;
112     }
113 }
114
115 bool DLList::push(void* data) {
116     DLListNode* node = new DLListNode(last, data, NULL);
117     /* Si obtenemos la memoria bien, actualizamos lo que sea necesario. */
118     if (node) {
119         /* Apunto el nodo actual al nuevo nodo. */
120         curr = node;
121         /* Si la lista está vacía hay que hacer apuntar todo al nuevo nodo. */
122         if (first == NULL) {
123             first = node;
124             last  = node;
125         /* Si no está vacía. */
126         } else {
127             /* Apunto el próximo nodo del último nodo de la lista al nuevo. */
128             last->next = node;
129             /* Apunto el último nodo de la lista al nuevo. */
130             last = node;
131         }
132         return true;
133     } else {
134         return false;
135     }
136 }
137
138 void* DLList::shift(void) {
139     // Si está vacía devuelve NULL.
140     if (first == NULL)  {
141         return NULL;
142     }
143     /* Primer nodo */
144     DLListNode* node = first;
145     /* Datos del primer nodo. */
146     void* data = node->data;
147     /* Pongo como primer nodo al siguiente. */
148     first = node->next;
149     /* Pongo al primero como nodo actual. */
150     curr = first;
151     /* Si era el único pongo el último en NULL. */
152     if (!first) {
153         last = NULL;
154     /* Si no, pongo el anterior en NULL. */
155     } else {
156         first->prev = NULL;
157     }
158     /* Libero memoria del nodo. */
159     delete node;
160     // Devuelvo elemento.
161     return data;
162 }
163
164 void* DLList::pop(void) {
165     // Si está vacía devuelve NULL.
166     if (first == NULL)  {
167         return NULL;
168     }
169     /* Último nodo */
170     DLListNode* node = last;
171     /* Datos del último nodo. */
172     void* data = node->data;
173     /* Pongo como último nodo al anterior. */
174     last = node->prev;
175     /* Pongo al último como nodo actual. */
176     curr = last;
177     /* Si era el único pongo el primero en NULL. */
178     if (!last) {
179         first = NULL;
180     /* Si no, pongo el siguiente en NULL. */
181     } else {
182         last->next = NULL;
183     }
184     /* Libero memoria del nodo. */
185     delete node;
186     // Devuelvo elemento.
187     return data;
188 }
189
190 void* DLList::remove_current(void) {
191     // Si no hay un nodo seleccionado devuelve NULL.
192     if (curr == NULL)  {
193         return NULL;
194     }
195     /* Nodo actual */
196     DLListNode* new_curr = curr;
197     /* Datos del nodo actual. */
198     void* data = new_curr->data;
199     /* Si tiene siguiente. */
200     if (new_curr->next) {
201         /* Se pone como anterior del siguiente al anterior del actual. */
202         new_curr->next->prev = new_curr->prev;
203     /* Si no tiene siguiente, se pone como último al anterior del actual. */
204     } else {
205         last = new_curr->prev;
206     }
207     /* Si tiene anterior. */
208     if (new_curr->prev) {
209         /* Se pone como siguiente del anterior al siguiente del actual. */
210         new_curr->prev->next = new_curr->next;
211     /* Si no tiene anterior, se pone como primero al siguiente del actual. */
212     } else {
213         first = new_curr->next;
214     }
215     /* Pongo como elemento actual al próximo elemento. */
216     curr = new_curr->next;
217     /* Libero memoria del nodo. */
218     delete new_curr;
219     // Devuelvo elemento.
220     return data;
221 }
222