]>
Commit | Line | Data |
---|---|---|
85ce9d3e | 1 | #ifndef LIST_H |
2 | #define LIST_H | |
3 | ||
4 | #include <iostream.h> | |
5 | #include <cassert> | |
6 | #include "listnode.h" | |
7 | #include "aClient.h" | |
8 | ||
9d057db5 | 9 | |
85ce9d3e | 10 | template <class T> |
11 | class List { | |
12 | public: | |
13 | List(); //constructor | |
14 | ~List(); //deconstructor | |
15 | void insertAtFront( const T & ); | |
16 | void insertAtBack( T *&); | |
17 | bool removeFromFront( T & ); | |
18 | bool removeFromBack( T & ); | |
19 | bool remove( T * ); | |
20 | bool isEmpty() const; | |
21 | void print() const; | |
1cf88153 | 22 | ListNode < T > *Find( T * ); |
85ce9d3e | 23 | ListNode < T > *First() { return firstPtr; }; |
24 | ListNode < T > *Last() { return lastPtr; }; | |
25 | private: | |
26 | ListNode < T > *firstPtr; | |
27 | ListNode < T > *lastPtr; | |
28 | ||
29 | ListNode < T > *getNewNode ( const T & ); | |
30 | }; | |
31 | ||
32 | template <class T> | |
33 | List<T>::List() : firstPtr (0), lastPtr (0) {} | |
34 | ||
35 | template <class T> | |
36 | List<T>::~List() | |
37 | { | |
38 | if (!isEmpty()) | |
39 | { | |
40 | cout << "Destroying Nodes" << endl; | |
41 | ||
42 | ListNode<T> *currentPtr = firstPtr, *tempPtr; | |
43 | ||
0a1518fa | 44 | while (currentPtr) |
85ce9d3e | 45 | { |
46 | tempPtr = currentPtr; | |
0a1518fa | 47 | currentPtr = currentPtr->Next(); |
0a1518fa | 48 | cout << "Deleting Memory address: " << tempPtr->getData() << endl << flush; |
49 | ||
85ce9d3e | 50 | delete tempPtr; |
85ce9d3e | 51 | } |
52 | cout << "All Nodes destroyed" << endl; | |
53 | } | |
54 | } | |
55 | ||
56 | template<class T> | |
57 | void List<T>::insertAtFront( const T &value ) | |
58 | { | |
59 | ListNode<T> *newPtr = getNewNode ( value ); | |
60 | ||
61 | ||
62 | if (isEmpty()) | |
63 | firstPtr = lastPtr = newPtr; | |
64 | else | |
65 | { | |
66 | newPtr->Next = firstPtr; | |
67 | firstPtr->prev = newPtr; | |
68 | firstPtr = newPtr; | |
69 | } | |
70 | } | |
71 | ||
72 | template<class T> | |
73 | void List<T>::insertAtBack(T *&value ) | |
74 | { | |
75 | ListNode<T> *newPtr = getNewNode(*value); | |
76 | ||
77 | if (isEmpty()) | |
78 | { | |
79 | firstPtr = lastPtr = newPtr; | |
80 | } | |
81 | else | |
82 | { | |
83 | newPtr->prev = lastPtr; | |
84 | lastPtr->next = newPtr; | |
85 | lastPtr = newPtr; | |
86 | } | |
87 | } | |
88 | ||
89 | ||
90 | template <class T> | |
91 | bool List<T>::removeFromFront( T &value ) | |
92 | { | |
93 | if ( isEmpty()) | |
94 | return false; | |
95 | else | |
96 | { | |
97 | ListNode<T> *tempPtr = firstPtr; | |
98 | ||
99 | if ( firstPtr == lastPtr ) | |
100 | firstPtr = lastPtr = 0; | |
101 | else | |
102 | firstPtr = firstPtr->next; | |
103 | ||
104 | value = tempPtr->getData(); | |
105 | delete tempPtr; | |
106 | return true; | |
107 | } | |
108 | } | |
109 | ||
110 | template <class T> | |
111 | bool List<T>::removeFromBack( T &value ) | |
112 | { | |
113 | if ( isEmpty() ) | |
114 | return false; | |
115 | else | |
116 | { | |
117 | ListNode<T> *tempPtr = lastPtr; | |
118 | ||
119 | if ( firstPtr == lastPtr ) | |
120 | lastPtr = firstPtr = 0; | |
121 | else | |
122 | lastPtr = lastPtr->prev; | |
123 | ||
124 | value = tempPtr->getData(); | |
125 | delete tempPtr; | |
126 | return true; | |
127 | ||
128 | } | |
129 | } | |
130 | ||
131 | template <class T> | |
132 | bool List<T>::isEmpty() const | |
0a1518fa | 133 | { return firstPtr == 0 && lastPtr == 0; } |
85ce9d3e | 134 | |
135 | template <class T> | |
136 | ListNode<T> *List<T>::getNewNode( const T &value) | |
137 | { | |
138 | ListNode<T> *ptr = new ListNode<T>(value); | |
139 | ||
140 | assert( ptr != 0); | |
141 | ||
142 | return ptr; | |
143 | } | |
1cf88153 | 144 | template<class T> |
145 | ListNode<T> *List<T>::Find( T *value ) | |
146 | { | |
147 | if (isEmpty()) {return NULL;} | |
148 | ||
149 | ListNode<T> *currentPtr; | |
150 | currentPtr = firstPtr; | |
151 | while (currentPtr) | |
152 | { | |
153 | if (currentPtr->getData() == value) | |
154 | return currentPtr; | |
155 | currentPtr = currentPtr->Next(); | |
156 | } | |
157 | return NULL; | |
158 | } | |
85ce9d3e | 159 | |
160 | template <class T> | |
161 | void List<T>::print() const | |
162 | { | |
163 | if (isEmpty()) | |
164 | { | |
165 | cout << "Empty list" << endl; | |
166 | return; | |
167 | } | |
168 | ||
169 | ListNode<T> *currentPtr; | |
170 | currentPtr = firstPtr; | |
171 | while (currentPtr) | |
172 | { | |
cdc9a6db | 173 | cout << "aClient: " << *currentPtr->getData() << flush; |
85ce9d3e | 174 | |
175 | if (currentPtr->getData()->stats) | |
cdc9a6db | 176 | cout << " Player Name: " << currentPtr->getData()->stats->name |
177 | << " Password: " << currentPtr->getData()->stats->password << flush; | |
85ce9d3e | 178 | cout << endl; |
179 | currentPtr = currentPtr->next; | |
180 | } | |
181 | ||
85ce9d3e | 182 | } |
183 | ||
184 | template <class T> | |
185 | bool List<T>::remove(T *remPtr) | |
186 | { | |
187 | ListNode<T> *newPtr = firstPtr; | |
188 | T *testPtr; | |
189 | ||
0a1518fa | 190 | if (isEmpty()) |
191 | return false; | |
192 | ||
85ce9d3e | 193 | while (newPtr) |
194 | { | |
195 | testPtr = newPtr->getData(); | |
196 | if (testPtr == remPtr) | |
197 | { | |
198 | if (firstPtr == lastPtr) | |
199 | { | |
0a1518fa | 200 | cout << "One Element. Deleting it" << endl << flush; |
201 | firstPtr = lastPtr = NULL; | |
85ce9d3e | 202 | delete newPtr; |
203 | return true; | |
204 | } | |
205 | else if (newPtr != lastPtr && newPtr != firstPtr) | |
206 | { | |
0a1518fa | 207 | cout << "Many elements, this one is in the middle. Deleting it" |
208 | << ", linking front to back, and back to front." << endl << flush; | |
85ce9d3e | 209 | newPtr->prev->next = newPtr->next; |
210 | newPtr->next->prev = newPtr->prev; | |
211 | delete newPtr; | |
212 | return true; | |
213 | } | |
214 | else if (newPtr == lastPtr) | |
215 | { | |
0a1518fa | 216 | cout << "This was the last element. Deleting it, and pointing the tail to " |
217 | << "its previous element." << endl << flush; | |
85ce9d3e | 218 | lastPtr = newPtr->prev; |
219 | lastPtr->next = 0; | |
220 | delete newPtr; | |
221 | return true; | |
222 | } | |
223 | else if (newPtr == firstPtr) | |
224 | { | |
0a1518fa | 225 | cout << "This was the first element. Deleting it, and pointing the head to " |
226 | << "its next element." << endl << flush; | |
85ce9d3e | 227 | firstPtr = newPtr->next; |
228 | firstPtr->prev = 0; | |
229 | delete newPtr; | |
230 | return true; | |
231 | } | |
232 | } | |
233 | newPtr = newPtr->next; | |
234 | } | |
235 | return false; | |
236 | } | |
237 | #endif |