1
+ public class MyLinkedList <E > extends MyAbstractList <E > {
2
+ private Node <E > head , tail ;
3
+
4
+ /** Create a default list */
5
+ public MyLinkedList () {
6
+ }
7
+
8
+ /** Create a list from an array of objects */
9
+ public MyLinkedList (E [] objects ) {
10
+ super (objects );
11
+ }
12
+
13
+ /** Return the head element in the list */
14
+ public E getFirst () {
15
+ if (size == 0 ) {
16
+ return null ;
17
+ }
18
+ else {
19
+ return head .element ;
20
+ }
21
+ }
22
+
23
+ /** Return the last element in the list */
24
+ public E getLast () {
25
+ if (size == 0 ) {
26
+ return null ;
27
+ }
28
+ else {
29
+ return tail .element ;
30
+ }
31
+ }
32
+
33
+ /** Add an element to the beginning of the list */
34
+ public void addFirst (E e ) {
35
+ Node <E > newNode = new Node <>(e ); // Create a new node
36
+ newNode .next = head ; // link the new node with the head
37
+ head = newNode ; // head points to the new node
38
+ size ++; // Increate list size
39
+
40
+ if (tail == null ) // The new node is the only node in list
41
+ tail = head ;
42
+ }
43
+
44
+ /** Add an element to the end of the list */
45
+ public void addLast (E e ) {
46
+ Node <E > newNode = new Node <>(e ); // Create a new node for e
47
+ if (tail == null ) {
48
+ head = tail = newNode ; // The on;y node in list
49
+ }
50
+ else {
51
+ tail .next = newNode ; // Link the new node with the last node
52
+ tail = tail .next ; // tail now points to the last node
53
+ }
54
+
55
+ size ++; // Increase size
56
+ }
57
+
58
+ @ Override /** Add a new element at the specified index
59
+ * in this list. The lndex of the head element is 0 */
60
+ public void add (int index , E e ) {
61
+ if (index == 0 ) addFirst (e ); // Insert first
62
+ else if (index >= size ) addLast (e ); // Insert last
63
+ else { // Insert in the middle
64
+ Node <E > current = head ;
65
+ for (int i = 1 ; i < index ; i ++)
66
+ current = current .next ;
67
+ Node <E > temp = current .next ;
68
+ current .next = new Node <>(e );
69
+ (current .next ).next = temp ;
70
+ size ++;
71
+ }
72
+ }
73
+
74
+ /** Remove the head node and
75
+ * return the object that is contained in the removed node. */
76
+ public E removeFirst () {
77
+ if (size == 0 ) return null ; // Nothing to delete
78
+ else {
79
+ Node <E > temp = head ; // keep the first node temporarily
80
+ head = head .next ; // Move head to point to next node
81
+ size --; // Reduce size by 1
82
+ return temp .element ; // Return the deleted element
83
+ }
84
+ }
85
+
86
+ /** Remove the last node and
87
+ * return the object that is contained in the removed node. */
88
+ public E removeLast () {
89
+ if (size == 0 ) return null ; // Nothing to remove
90
+ else if (size == 1 ) { // Only one element in the list
91
+ Node <E > temp = head ;
92
+ head = tail = null ; // list becomes empty
93
+ size = 0 ;
94
+ return temp .element ;
95
+ }
96
+ else {
97
+ Node <E > current = head ;
98
+
99
+ for (int i = 0 ; i < size - 2 ; i ++)
100
+ current = current .next ;
101
+
102
+ Node <E > temp = tail ;
103
+ tail = current ;
104
+ tail .next = null ;
105
+ size --;
106
+ return temp .element ;
107
+ }
108
+ }
109
+
110
+ @ Override /** Remove the element at the specified position in this
111
+ * list. Return the element that was removed from the list. */
112
+ public E remove (int index ) {
113
+ if (index < 0 || index >= size ) return null ; // Out of range
114
+ else if (index == 0 ) return removeFirst (); // Remove first
115
+ else if (index == size - 1 ) return removeLast (); // Remove last
116
+ else {
117
+ Node <E > previous = head ;
118
+
119
+ for (int i = 1 ; i < index ; i ++) {
120
+ previous = previous .next ;
121
+ }
122
+
123
+ Node <E > current = previous .next ;
124
+ previous .next = current .next ;
125
+ size --;
126
+ return current .element ;
127
+ }
128
+ }
129
+
130
+ @ Override
131
+ public String toString () {
132
+ StringBuilder result = new StringBuilder ("[" );
133
+
134
+ Node <E > current = head ;
135
+ for (int i = 0 ; i < size ; i ++) {
136
+ result .append (current .element );
137
+ current = current .next ;
138
+ if (current != null ) {
139
+ result .append (", " ); // Separate two elements with a comma
140
+ }
141
+ else {
142
+ result .append ("]" ); // Insert the closing ] in the string
143
+ }
144
+ }
145
+
146
+ return result .toString ();
147
+ }
148
+
149
+ @ Override /** Clear the list */
150
+ public void clear () {
151
+ size = 0 ;
152
+ head = tail = null ;
153
+ }
154
+
155
+ @ Override /** Return true if this list contains the element e */
156
+ public boolean contains (E e ) {
157
+ if (size == 0 ) return false ;
158
+ else {
159
+ Node <E > current = head ;
160
+
161
+ while (current != null ) {
162
+ if (current .element == e )
163
+ return true ;
164
+ current = current .next ;
165
+ }
166
+ }
167
+ return false ;
168
+ }
169
+
170
+ @ Override /** Return the element at the specified index */
171
+ public E get (int index ) {
172
+ if (index < 0 || index >= size ) return null ; // Out of range
173
+ else if (index == 0 ) return getFirst ();
174
+ else if (index == size - 1 ) return getLast ();
175
+ else {
176
+ Node <E > current = head .next ;
177
+
178
+ for (int i = 1 ; i < index ; i ++)
179
+ current = current .next ;
180
+ return current .element ;
181
+ }
182
+
183
+ }
184
+
185
+ @ Override /** Return the index of the head matching element
186
+ * in this list. Return -1 if no match. */
187
+ public int indexOf (E e ) {
188
+ if (head .element == e ) return 0 ;
189
+ else if (tail .element == e ) return size - 1 ;
190
+ else {
191
+ Node <E > current = head .next ;
192
+ int index = 1 ;
193
+ while (current != null ) {
194
+ if (current .element == e )
195
+ return index ;
196
+ current = current .next ;
197
+ index ++;
198
+ }
199
+ }
200
+ return -1 ;
201
+ }
202
+
203
+ @ Override /** Return the index of the last matching element
204
+ * in this list. Rreturn -1 if on match. */
205
+ public int lastIndexOf (E e ) {
206
+ int index = -1 ;
207
+ Node <E > current = head ;
208
+ for (int i = 0 ; i < size ; i ++) {
209
+ if (current .element == e )
210
+ index = i ;
211
+ current = current .next ;
212
+ }
213
+
214
+ return index ;
215
+ }
216
+
217
+ @ Override /** Replace the element at the specified position
218
+ * in this list with the specified element. */
219
+ public E set (int index , E e ) {
220
+ if (index < 0 || index > size - 1 ) return null ;
221
+ else {
222
+ Node <E > current = head ;
223
+ for (int i = 0 ; i < index ; i ++)
224
+ current = current .next ;
225
+
226
+ current .element = e ;
227
+ return current .element ;
228
+ }
229
+ }
230
+
231
+ @ Override /** Override iterator() defined in Iterable */
232
+ public java .util .Iterator <E > iterator () {
233
+ return new LinkedListIterator ();
234
+ }
235
+
236
+ public class LinkedListIterator
237
+ implements java .util .Iterator <E > {
238
+ private Node <E > current = head ; // Current index
239
+
240
+ @ Override
241
+ public boolean hasNext () {
242
+ return (current != null );
243
+ }
244
+
245
+ @ Override
246
+ public E next () {
247
+ E e = current .element ;
248
+ current = current .next ;
249
+ return e ;
250
+ }
251
+
252
+ @ Override
253
+ public void remove () {
254
+ System .out .println ("Implementation left as an exercise" );
255
+ }
256
+ }
257
+
258
+ // This class is only used in LinkedList, so it is private.
259
+ // This class does not need to access any
260
+ // instance members of LinkedList, so it is defined static.
261
+ private static class Node <E > {
262
+ E element ;
263
+ Node <E > next ;
264
+
265
+ public Node (E element ) {
266
+ this .element = element ;
267
+ }
268
+ }
269
+ }
0 commit comments