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