Repository navigation
Expand file tree
/
Copy pathDoubleLinkedList.java
More file actions
380 lines (320 loc) · 10.7 KB
/
Copy pathDoubleLinkedList.java
File metadata and controls
380 lines (320 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
import java.util.*;
public class DoubleLinkedList<E> extends AbstractSequentialList<E> implements List<E>
{ // Data fields
private Node<E> head; // points to the head of the list
private Node<E> tail; //points to the tail of the list
private int size = 0; // the number of items in the list
//default constructor
public DoubleLinkedList() {
this.setAll(null, null, 0);
}
@Override
public String toString() {
//toString method to display the linked list
ListIterator iter = listIterator();
String other = "[";
while(iter.hasNext()) {
other += iter.next();
if(iter.hasNext()) {
other += ", ";
}
}
return other + "]";
}
@Override
public boolean equals(Object o) {
DoubleLinkedList other = (DoubleLinkedList) o;
if(this.toString() == (other.toString())) {
return true;
}
else {
return false;
}
}
@Override
public boolean contains(Object o) {
if(this.size == 0) {
return false;
}
//iterate through the list to find if an Object with the value specified exists in the list using equals
ListIterator iter = listIterator();
while(iter.hasNext()) {
if(iter.next().equals(o)) {
return true;
}
}
return false;
}
@Override
public boolean add(E e) {
listIterator(this.size).add(e);
return true;
}
@Override
public void clear() {
head = null;
tail = null;
size = 0;
}
public void setAll(Node<E> head, Node<E> tail, int size) {
this.head = head;
this.tail = tail;
this.size = size;
}
@Override
public void add(int index, E obj)
{
listIterator(index).add(obj);
}
@Override
public int indexOf(Object o) {
ListIterator iter = listIterator();
int index = 0;
//iterate through the list from index 0 and find the object by its value and return its index
while(iter.hasNext()) {
Object other = iter.next();
if(other.equals(o)) {
return index;
}
index++;
}
return -1;
}
@Override
public int lastIndexOf(Object o) {
int index = -1, count = 0;
//if list is not empty then iterate through the list from index 0 and find the object by its value and return its last index
if(this.size != 0) {
ListIterator iter = listIterator(0);
while (iter.hasNext()) {
Object other = iter.next();
if (other.equals(o)) {
index = count;
}
count++;
}
}
return index;
}
public void addFirst(E obj) {
head = new Node<>(obj);
size++;
}
public void addLast(E obj) {
tail = new Node<>(obj);
size++;
}
@Override
public E get(int index)
{
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
ListIterator<E> iter = listIterator(index);
return iter.next();
}
public E getFirst() { return head.data; }
public E getLast() { return tail.data; }
@Override
public int size() {
//returns size of the list
return this.size;
}
@Override
public E remove(int index)
{ E returnValue = null;
ListIterator<E> iter = listIterator(index);
if (iter.hasNext())
{ returnValue = iter.next();
iter.remove();
}
else { throw new IndexOutOfBoundsException(); }
return returnValue;
}
public boolean remove(Object o) {
//iterating through the list to find the object by its value and remove it using iteraor remove method
ListIterator<E> iter = listIterator(0);
while(iter.hasNext()) {
Object other = iter.next();
if(other.equals(o)) {
iter.remove();
return true;
}
}
return false;
}
@Override
public E set(int index, E element) {
//error checking if the index is in the range
if(size == 0 || index >= size || element == null) {
throw new IndexOutOfBoundsException();
}
ListIterator<E> iter = listIterator(index);
E setValue = null;
setValue = iter.next();
iter.set(element);
return setValue;
}
@Override
public Iterator<E> iterator() {
return new ListIter(0);
}
@Override
public ListIterator<E> listIterator() {
return new ListIter(0);
}
@Override
public ListIterator<E> listIterator(int index){
return new ListIter(index);
}
@Override
public boolean isEmpty() {
return (head == null);
}
// Inner Classes
private static class Node<E>
{ private E data;
private Node<E> next = null;
private Node<E> prev = null;
public Node() {
this.next = null;
this.prev = null;
this.data = null;
}
private Node(E dataItem) //constructor
{ data = dataItem; }
} // end class Node
public class ListIter implements ListIterator<E>
{
private Node<E> nextItem; // the current node
private Node<E> lastItemReturned; // the previous node
private int index = 0; //
public ListIter(int i) // constructor for ListIter class
{ if (i < 0 || i > size)
{
throw new IndexOutOfBoundsException();
}
lastItemReturned = null;
if (i == size) // Special case of last item
{ index = size; nextItem = null; }
else // start at the beginning
{ nextItem = head;
for (index = 0; index < i; index++) nextItem = nextItem.next;
}// end else
} // end constructor
public ListIter(ListIter other)
{ nextItem = other.nextItem;
index = other.index; }
public boolean hasNext() {
return nextItem != null; }
public boolean hasPrevious()
{
return index > 0;
}
public int previousIndex() {
return index-1; } // Fill Here
public int nextIndex() {
return index; } // Fill here
@Override
public void set(E e) {
//error checking if the lastItemReturned is null therefore it can't be set
if (lastItemReturned == null)
{
throw new IllegalStateException();
}
//if no error then change or replace the data in the lastItemReturned with the new data provided and then remove the lastItemReturned
lastItemReturned.data = e;
lastItemReturned = null;
}
@Override
public void remove(){
//error checking if the list is empty and the last item returned is null
if(size == 0 || lastItemReturned == null) {
throw new IllegalStateException();
}
else {
//if there is only one node in the list then just remove it
if(size == 1) {
head = null;
}
//if we like to remove the fist node in the list
else if(lastItemReturned.prev == null) {
head = nextItem;
nextItem.prev = null;
}
//if we like to remove the last node in the list
else if(lastItemReturned.next == null) {
lastItemReturned.prev.next = null;
}
//if we like to remove a node in the middle of the list
else {
lastItemReturned.prev.next = lastItemReturned.next;
lastItemReturned.next.prev = lastItemReturned.prev;
}
//decrease the size and set the lastItemRetuned to null
size--;
lastItemReturned = null;
}
} // implemented
public E next()
{
//error checking if an element exists
if(!(hasNext())) {
throw new NoSuchElementException();
}
//set the lastItemReturned to the nextItem and increase the index to move forward in the list
lastItemReturned = nextItem;
nextItem = nextItem.next;
index++;
return lastItemReturned.data;
}
public E previous()
{
if(!(hasPrevious())) {
throw new NoSuchElementException();
}
if(nextItem == null) {
nextItem = tail;
}
else {
nextItem = nextItem.prev;
}
lastItemReturned = nextItem;
index--;
return lastItemReturned.data;
}
public void add(E obj) {
//if adding to an empty list
if(head == null) {
head = new Node<>(obj);
tail = head;
}
//if adding to the beginning of the list at index 0
else if(nextItem == head) {
Node<E> newNode = new Node<>(obj);
newNode.next = nextItem;
nextItem.prev = newNode;
head = newNode;
}
//if adding at the tail of the list if index is size - 1
else if(nextItem == null) {
Node<E> newNode = new Node<>(obj);
tail.next = newNode;
newNode.prev = tail;
tail = newNode;
}
//if none of the above are true then we are adding in the middle of the list
else {
Node<E> newNode = new Node<>(obj);
newNode.prev = nextItem.prev;
nextItem.prev.next = newNode;
newNode.next = nextItem;
nextItem.prev = newNode;
}
//increasing the size of the list and the index after adding the new node
size++;
index++;
lastItemReturned = null;
} // End of add method
}// end of inner class ListIter
}// end of class DoubleLinkedList