-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathDoublyLinkedList.java
More file actions
277 lines (244 loc) · 10.8 KB
/
Copy pathDoublyLinkedList.java
File metadata and controls
277 lines (244 loc) · 10.8 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
package Unit_1_Labs_LinkedList;
/*
Implement the class DoublyLinkedList.
You will implement a fully functioning and working Doubly Linked List class that meets the criteria of a specific API.
Your DoublyLinkedList class will link Node objects, whose data will be of a generic type.
This data structure must be implemented without the use of arrays, ArrayLists, or any additional libraries.
In other words, you're building this class from scratch.
You may (and should), however, reference your SinglyLinkedList class to remind you of how to implement some of the basic methods.
The Node class
Field summary
• data: T: Each Node object will store data of generic type.
• next: Node: Each Node stores a reference to the Node that follows this node. If there is no such node, next should be null.
• previous: Node: Each Node stores a reference to the Node that precedes this node. If there is no such node, previous should be null.
Constructor summary
• Node(): This parameter-less constructor should assign data, next, and previous to null.
• Node(T value): This single-parameter constructor should assign data to value and next and previous to null.
The DoublyLinkedList class
Field summary
• head: Node: A reference to the Node that is the beginning of this DoublyLinkedList.
Constructor summary
• DoublyLinkedList(): This parameter-less constructor should assign head to null.
• DoublyLinkedList(T value): This single-parameter constructor should assign head to a Node whose data is assigned to value.
Method summary
• isEmpty(): boolean: Returns true if this linked list is empty, i.e. there are no nodes in the list.
• size(): int: Returns the number of nodes in this linked list.
• toString(): String: Returns a String representation of this linked list. The output of the String should be in the format:
null <-- node1.data <--> node2.data <--> node3.data <--> ... --> null
Each node's data should bepreceded by a two-dash arrow pointing to its previous node, and then the node is followed by a space, two dashes, a greater than symbol, and a space.
The last node should only point to null. The start and end of the returned String should includereferences to null. In the case of an empty list,just return the String literal, "null".
• get(int index): int: Returns the value stored in the specified place in this linked list. If index is invalid, this method should thrown an IndexOutOfBoundsException. Read about how to throw an exception here. <https://www.webucator.com/how-to/how-throw-an-exception-java.cfm>
• contains(int value): boolean: Returns true if there is a Node in the linked list whose data is equal to value and returns false otherwise. Make sure to use value comparison in your equality check, not reference comparison!
• add(T value): void: Creates a new Node whose data is value, and appends this new Node to the end of this linked list.
• add(int index, T value): void: Inserts a new Node whose data is value at the specified position in this list. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). If index is invalid, this method should throw an IndexOutOfBoundsException.
• remove(): T: Retrieves and removes the head (first element) of this linked list. The Node that came after head should become the new head. If this list is empty when remove is called, throw a NoSuchElementException.
• remove(int index): T: Removes the data of the Node at the specified position in this list. Shifts any subsequent elements to the left (subtracts one from their indices). Returns the data of the Node that was removed from the list. If index is invalid, this method should throw an IndexOutOfBoundsException.
*/
import java.util.NoSuchElementException;
public class DoublyLinkedList<T> {
static class Node<T> {
T data;
Node<T> next;
Node<T> previous;
Node() {
this.data = null;
this.next = null;
this.previous = null;
}
Node(T value) {
this.data = value;
this.next = null;
this.previous = null;
}
Node(T value, Node<T> prev, Node<T> next) {
this.data = value;
this.previous = prev;
this.next = next;
}
}
private Node<T> head;
private int size = 0;
public DoublyLinkedList() {
head = null;
}
public DoublyLinkedList(T value) {
head = new Node<T>(value);
size++;
}
/*
*isEmpty(): boolean: Returns true if this linked list is empty, i.e. there are no nodes in the list.
*/
public boolean isEmpty() {
return (head == null);
}
/*
* size(): int: Returns the number of nodes in this linked list.
*/
public int size() {
return size;
}
/*
* toString(): String: Returns a String representation of this linked list.
* The output of the String should be in the format:
* "null <-- node1.data <--> node2.data <--> node3.data <--> ... --> null"
* Each node's data should bepreceded by a two-dash arrow pointing to its previous node,
* and then the node is followed by a space, two dashes, a greater than symbol, and a space.
* The last node should only point to null.
* The start and end of the returned String should includereferences to null.
* In the case of an empty list,just return the String literal, "null".
*/
public String toString() {
String retVal = "null";
Node<T> temp = head;
if (temp == null) {
return retVal;
}
else {
retVal += " <-- ";
while (temp.next != null) {
retVal += (temp.data + " <--> ");
temp = temp.next;
}
retVal += temp.data + " --> null";
return retVal;
}
}
/*
* get(int index): int: Returns the value stored in the specified place in this linked list.
* If index is invalid, this method should thrown an IndexOutOfBoundsException.
*/
public T get(int index) {
if (index >= size()) {
throw new IndexOutOfBoundsException();
}
else {
Node<T> temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp.data;
}
}
/*
* contains(int value): boolean: Returns true if there is a Node in the linked list whose data is equal to value and returns false otherwise.
* Make sure to use value comparison in your equality check, not reference comparison!
*/
public boolean contains(T value) {
Node<T> temp = head;
while (temp != null) {
if (temp.data.equals(value)) {
return true;
}
temp = temp.next;
}
return false;
}
/*
* add(T value): void: Creates a new Node whose data is value, and appends this new Node to the end of this linked list.
*/
public void add(T value) {
if (isEmpty()) {
head = new Node<T>(value);
}
else {
Node<T> temp = head;
Node<T> prev = null;
while (temp.next != null) {
prev = temp;
temp = temp.next;
}
temp.next = new Node<T>(value);
temp.previous = prev;
}
size++;
}
/*
* add(int index, T value): void: Inserts a new Node whose data is value at the specified position in this list.
* Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices).
* If index is invalid, this method should throw an IndexOutOfBoundsException.
*/
public void add(int index, T value) {
//check if out of bounds
if (index < 0 || index > size()) {
throw new IndexOutOfBoundsException();
}
// if its at 0 handle case
if (index == 0) {
head = new Node<T>(value, null, head);
}
// iterate through index -1
else {
Node<T> temp = head;
for (int i = 0; i < (index - 1); i++) {
temp = temp.next;
}
temp = new Node<T>(value, temp, temp.next);
temp.previous.next = temp;
temp.next.previous = temp;
}
size++;
}
/*
* remove(): T: Retrieves and removes the head (first element) of this linked list.
* The Node that came after head should become the new head.
* If this list is empty when remove is called, throw a NoSuchElementException.
*/
public T remove() {
Node<T> retVal = head;
if (isEmpty()) {
throw new NoSuchElementException();
}
else {
head = head.next;
size--;
if (size != 0){
head.previous = null;
}
}
return retVal.data;
}
/*
* remove(int index): T: Removes the data of the Node at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their indices). \
* Returns the data of the Node that was removed from the list.
* If index is invalid, this method should throw an IndexOutOfBoundsException.
*/
public T remove(int index) {
// Index out of bounds exception
if (index >= size() || index < 0) {
throw new IndexOutOfBoundsException();
}
else {
// Temporary list
Node<T> temp = head;
// Iterate to node at index
for (int i = 0; i < index; i++) {
temp = temp.next;
}
// Create the returnable var
T retVal = temp.data;
// prev and next both null case
if (temp.previous == null && temp.next == null) {
head = null;
}
// only prev null case
else if (temp.previous == null) {
temp.next.previous = null;
}
// only next null case
else if (temp.next == null) {
temp.previous.next = null;
}
// prev and next non-null
else {
// reset pointers
temp.previous.next = temp.next;
temp.next.previous = temp.previous;
}
// decrement size
size--;
// return the return var
return retVal;
}
}
}