]> git.llucax.com Git - z.facultad/75.42/euler-oo.git/blob - dllist.cpp
Se homogeiniza y se agregan comentarios.
[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), _current(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     _current = _first;
46     /* Si hay un nodo, devulevo sus datos, si no NULL. */
47     return _current ? _current->data : NULL;
48 }
49
50 void* DLList::end(void) {
51     _current = _last;
52     /* Si hay un nodo, devulevo sus datos, si no NULL. */
53     return _current ? _current->data : NULL;
54 }
55
56 bool DLList::have_more(void) {
57     return _current != NULL;
58 }
59
60 void* DLList::current(void) {
61     return _current ? _current->data : NULL;
62 }
63
64 void* DLList::next(void) {
65     DLListNode* current = _current;
66     /* Si no está vacía ni ya fue terminada de recorrer. */
67     if (current) {
68         /* Apuntamos el actual al próximo. */
69         _current = current->next;
70         /* Devolvemos los datos del próximo o NULL si no había otro. */
71         return _current ? _current->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* current = _current;
80     /* Si no está vacía ni ya fue terminada de recorrer. */
81     if (current) {
82         /* Apuntamos el actual al anterior. */
83         _current = current->prev;
84         /* Devolvemos los datos del anterior o NULL si no había otro. */
85         return _current ? _current->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         _current = 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         _current = 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     _current = _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     return data;
161 }
162
163 void* DLList::pop(void) {
164     // Si está vacía devuelve NULL.
165     if (_first == NULL)  {
166         return NULL;
167     }
168     /* Último nodo */
169     DLListNode* node = _last;
170     /* Datos del último nodo. */
171     void* data = node->data;
172     /* Pongo como último nodo al anterior. */
173     _last = node->prev;
174     /* Pongo al último como nodo actual. */
175     _current = _last;
176     /* Si era el único pongo el primero en NULL. */
177     if (!_last) {
178         _first = NULL;
179     /* Si no, pongo el siguiente en NULL. */
180     } else {
181         _last->next = NULL;
182     }
183     /* Libero memoria del nodo. */
184     delete node;
185     return data;
186 }
187
188 void* DLList::remove_current(void) {
189     // Si no hay un nodo seleccionado devuelve NULL.
190     if (_current == NULL)  {
191         return NULL;
192     }
193     /* Nodo actual */
194     DLListNode* current = _current;
195     /* Datos del nodo actual. */
196     void* data = current->data;
197     /* Si tiene siguiente. */
198     if (current->next) {
199         /* Se pone como anterior del siguiente al anterior del actual. */
200         current->next->prev = current->prev;
201     /* Si no tiene siguiente, se pone como último al anterior del actual. */
202     } else {
203         _last = current->prev;
204     }
205     /* Si tiene anterior. */
206     if (current->prev) {
207         /* Se pone como siguiente del anterior al siguiente del actual. */
208         current->prev->next = current->next;
209     /* Si no tiene anterior, se pone como primero al siguiente del actual. */
210     } else {
211         _first = current->next;
212     }
213     /* Pongo como elemento actual al próximo elemento. */
214     _current = current->next;
215     /* Libero memoria del nodo. */
216     delete current;
217     return data;
218 }
219