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