Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
1
00:00:00,206 --> 00:00:02,542
(upbeat music)
2
2
00:00:02,542 --> 00:00:05,790
(keyboard clicking)
3
3
00:00:05,790 --> 00:00:09,500
In this video, we'll implement the doubly linked lists.
4
4
00:00:09,500 --> 00:00:11,970
To start us off, I've created a new project.
5
5
00:00:11,970 --> 00:00:13,660
I'm going to put the code into
6
6
00:00:13,660 --> 00:00:16,750
academy.learnProgramming.doublyLinkedLists,
7
7
00:00:16,750 --> 00:00:19,550
and what I've done is I've copied the classes from the
8
8
00:00:19,550 --> 00:00:21,720
singly linked list implementations.
9
9
00:00:21,720 --> 00:00:23,520
So in the main method,
10
10
00:00:23,520 --> 00:00:27,040
I've created the usual four employee instances.
11
11
00:00:27,040 --> 00:00:29,840
The employee class is exactly the same
12
12
00:00:29,840 --> 00:00:32,950
as we've been using in the previous videos.
13
13
00:00:32,950 --> 00:00:35,560
The employee node is what we implemented
14
14
00:00:35,560 --> 00:00:38,440
when we did the implementation of a singly linked list,
15
15
00:00:38,440 --> 00:00:41,830
and the same goes for employee doubly linked list.
16
16
00:00:41,830 --> 00:00:43,340
I've renamed the class,
17
17
00:00:43,340 --> 00:00:47,140
but right now it's a singly link list implementation.
18
18
00:00:47,140 --> 00:00:48,790
So the first thing we're going to do
19
19
00:00:48,790 --> 00:00:52,930
is add a previous field to our employee node class
20
20
00:00:52,930 --> 00:00:55,290
because now that we have a doubly linked list,
21
21
00:00:55,290 --> 00:00:58,420
every node is gonna have two references.
22
22
00:00:58,420 --> 00:01:03,420
So I'll say, private EmployeeNode previous,
23
23
00:01:03,520 --> 00:01:06,180
and I'll add sets and gets.
24
24
00:01:06,180 --> 00:01:08,033
I'll let the I to E do this for me.
25
25
00:01:09,850 --> 00:01:11,610
I'll right click, say generate.
26
26
00:01:11,610 --> 00:01:12,950
I want a setter and getter.
27
27
00:01:12,950 --> 00:01:14,710
It's only gonna offer me previous
28
28
00:01:14,710 --> 00:01:15,920
because it's smart enough to know
29
29
00:01:15,920 --> 00:01:19,260
that we already have sets and gets for everything else.
30
30
00:01:19,260 --> 00:01:20,303
And there we go.
31
31
00:01:22,130 --> 00:01:24,800
And so now our nodes are going to contain
32
32
00:01:24,800 --> 00:01:27,760
two references which we can also say two links,
33
33
00:01:27,760 --> 00:01:30,580
one to the next node, and one to the previous node.
34
34
00:01:30,580 --> 00:01:34,490
So now we need to update our link list implementation.
35
35
00:01:34,490 --> 00:01:36,760
We're going to add a field for the tail
36
36
00:01:36,760 --> 00:01:38,830
because in a doubly linked list,
37
37
00:01:38,830 --> 00:01:41,630
we have a field that points to the head,
38
38
00:01:41,630 --> 00:01:42,960
or the first node in the list,
39
39
00:01:42,960 --> 00:01:44,780
any field that points to the tail,
40
40
00:01:44,780 --> 00:01:46,770
or the last node in the list.
41
41
00:01:46,770 --> 00:01:49,993
So we'll say private, employee node,
42
42
00:01:51,630 --> 00:01:53,400
tail, and just like the head,
43
43
00:01:53,400 --> 00:01:55,350
this will be initialised to null so we don't need
44
44
00:01:55,350 --> 00:01:57,750
to create a constructor that does that.
45
45
00:01:57,750 --> 00:02:00,200
So when it comes to the add to front method,
46
46
00:02:00,200 --> 00:02:02,120
when we add a node to the front of the list,
47
47
00:02:02,120 --> 00:02:04,370
it's going to become the first node in the list,
48
48
00:02:04,370 --> 00:02:07,620
and so its previous field will always point to null,
49
49
00:02:07,620 --> 00:02:09,740
so we don't have to handle the previous field
50
50
00:02:09,740 --> 00:02:14,040
because the previous field in the employee node instance
51
51
00:02:14,040 --> 00:02:16,140
will always be initialised to null,
52
52
00:02:16,140 --> 00:02:19,430
so there's no need for us to set the previous field in here,
53
53
00:02:19,430 --> 00:02:22,860
but we're gonna have to change the previous field
54
54
00:02:22,860 --> 00:02:25,700
of the node that's currently at the head of the list
55
55
00:02:25,700 --> 00:02:29,760
because the previous field of the current head node
56
56
00:02:29,760 --> 00:02:32,550
will have to point to the node that we're adding
57
57
00:02:32,550 --> 00:02:34,690
because whatever's at the head of the list right now
58
58
00:02:34,690 --> 00:02:37,110
is going to become the second node in the list,
59
59
00:02:37,110 --> 00:02:40,160
and its previous field is going to point back
60
60
00:02:40,160 --> 00:02:41,740
to the node that we're adding.
61
61
00:02:41,740 --> 00:02:44,390
The other thing we have to handle in add to front
62
62
00:02:44,390 --> 00:02:48,600
is the case of when we're starting with an empty list
63
63
00:02:48,600 --> 00:02:50,540
because when we're starting with an empty list,
64
64
00:02:50,540 --> 00:02:52,990
both the head and the tail point to null,
65
65
00:02:52,990 --> 00:02:56,510
and when we add a node to an empty list when we're done,
66
66
00:02:56,510 --> 00:02:59,690
both the head and the tail should be pointing to the node.
67
67
00:02:59,690 --> 00:03:02,500
Now normally we wouldn't have to worry about the tail.
68
68
00:03:02,500 --> 00:03:05,780
If there's already one or more nodes in the list
69
69
00:03:05,780 --> 00:03:07,520
and we add a node to the front,
70
70
00:03:07,520 --> 00:03:10,590
the tail isn't going to change because we're growing
71
71
00:03:10,590 --> 00:03:12,640
the list from the head not from the tail.
72
72
00:03:12,640 --> 00:03:15,060
So the only time that we have to worry
73
73
00:03:15,060 --> 00:03:18,690
about setting the tail is if we're adding a node
74
74
00:03:18,690 --> 00:03:21,990
into an empty list, if this is the first node we're adding.
75
75
00:03:21,990 --> 00:03:23,970
So we need to make a couple of changes here.
76
76
00:03:23,970 --> 00:03:26,470
We have to check whether we're adding a node
77
77
00:03:26,470 --> 00:03:27,880
to an empty list, and if we are,
78
78
00:03:27,880 --> 00:03:30,380
we need to set the tail to that new node,
79
79
00:03:30,380 --> 00:03:33,470
and also if we're not adding into an empty list,
80
80
00:03:33,470 --> 00:03:37,280
then we need to change the current head's previous field
81
81
00:03:37,280 --> 00:03:38,750
to the node we're adding.
82
82
00:03:38,750 --> 00:03:42,250
So before we set the head, we're going to say,
83
83
00:03:42,250 --> 00:03:45,423
if head equals null,
84
84
00:03:46,490 --> 00:03:48,820
and we could call our is empty method two,
85
85
00:03:48,820 --> 00:03:50,660
but I'm gonna say head equals null to make
86
86
00:03:50,660 --> 00:03:52,140
it clear what we're doing here.
87
87
00:03:52,140 --> 00:03:54,600
If we're adding this node into an empty list,
88
88
00:03:54,600 --> 00:03:56,220
then we need to set the tail.
89
89
00:03:56,220 --> 00:03:58,440
So we'll say tail equals node.
90
90
00:03:58,440 --> 00:04:00,840
If we're not adding the node into an empty list,
91
91
00:04:00,840 --> 00:04:02,150
we don't need to worry about the tail.
92
92
00:04:02,150 --> 00:04:03,700
The tail isn't going to change.
93
93
00:04:03,700 --> 00:04:06,320
Okay, so if we're adding the node to an empty list,
94
94
00:04:06,320 --> 00:04:07,900
we set the tail to node.
95
95
00:04:07,900 --> 00:04:11,100
If the list is not empty, then we need to set
96
96
00:04:11,100 --> 00:04:15,790
the current head node's previous field to the new node.
97
97
00:04:15,790 --> 00:04:18,920
So we'll say else, head.setPrevious
98
98
00:04:22,270 --> 00:04:25,100
to the node that we're adding, and that's it.
99
99
00:04:25,100 --> 00:04:27,130
That's the only changes we have to make.
100
100
00:04:27,130 --> 00:04:30,200
Now up here, we're setting the next field of the new node
101
101
00:04:30,200 --> 00:04:33,130
to whatever head is, and if head is null, that's fine.
102
102
00:04:33,130 --> 00:04:35,760
If we're adding into an empty list,
103
103
00:04:35,760 --> 00:04:38,300
we want the next field to be null because the node
104
104
00:04:38,300 --> 00:04:40,790
we're adding is gonna be the only node in the list,
105
105
00:04:40,790 --> 00:04:42,410
and so there's nothing coming after it,
106
106
00:04:42,410 --> 00:04:44,120
and so its next field will be null.
107
107
00:04:44,120 --> 00:04:46,080
And as I mentioned earlier, we don't have to worry
108
108
00:04:46,080 --> 00:04:48,810
about setting the previous field of the node we're adding
109
109
00:04:48,810 --> 00:04:50,410
because that's always going to be null
110
110
00:04:50,410 --> 00:04:53,190
because it's being added as the first item in the list,
111
111
00:04:53,190 --> 00:04:55,010
so there's nothing before it.
112
112
00:04:55,010 --> 00:04:57,240
Okay, so add to front is done.
113
113
00:04:57,240 --> 00:04:59,650
Let me update our print list,
114
114
00:04:59,650 --> 00:05:02,460
and what I'm going to do is I'm gonna change
115
115
00:05:02,460 --> 00:05:05,030
this arrow to sort of like a double arrow
116
116
00:05:05,030 --> 00:05:07,370
so we know that there are two links,
117
117
00:05:07,370 --> 00:05:09,510
just to make that a little clearer,
118
118
00:05:09,510 --> 00:05:11,530
and now let's go to our main method,
119
119
00:05:11,530 --> 00:05:14,950
and let's add some employees to our doubly linked list.
120
120
00:05:14,950 --> 00:05:19,670
So we'll say EmployeeDoublyLinkedList, list
121
121
00:05:19,670 --> 00:05:24,090
equals new EmployeeDoublyLinkedList,
122
122
00:05:24,090 --> 00:05:26,040
and we'll say list.addToFront.
123
123
00:05:26,040 --> 00:05:26,980
There's nothing new here.
124
124
00:05:26,980 --> 00:05:29,060
We did this with the singly linked list.
125
125
00:05:29,060 --> 00:05:30,893
So we'll add Jane Jones,
126
126
00:05:32,800 --> 00:05:34,093
John Doe,
127
127
00:05:37,340 --> 00:05:39,290
Mary Smith, and
128
128
00:05:41,540 --> 00:05:42,533
Mike Wilson,
129
129
00:05:44,490 --> 00:05:46,073
and then we'll print our list,
130
130
00:05:47,100 --> 00:05:48,620
and let's get the size too
131
131
00:05:49,477 --> 00:05:51,990
just to make sure we're incrementing that size correctly,
132
132
00:05:51,990 --> 00:05:54,403
so we'll print list.getSize.
133
133
00:05:57,150 --> 00:05:58,363
All right, let's run.
134
134
00:06:03,910 --> 00:06:06,240
And we'll see that we have four employees,
135
135
00:06:06,240 --> 00:06:07,300
and just as before,
136
136
00:06:07,300 --> 00:06:09,000
because we're always adding to the front,
137
137
00:06:09,000 --> 00:06:11,720
we have Mike in the front position
138
138
00:06:11,720 --> 00:06:16,330
followed by Mary, followed by John, followed by Jane.
139
139
00:06:16,330 --> 00:06:19,410
That double arrow there is a single arrow.
140
140
00:06:19,410 --> 00:06:22,250
I could add a test here to see when we're looking
141
141
00:06:22,250 --> 00:06:24,660
at the last node, but I think you understand
142
142
00:06:24,660 --> 00:06:26,520
that null isn't pointing back.
143
143
00:06:26,520 --> 00:06:28,763
Jane Jones is just pointing to null.
144
144
00:06:30,130 --> 00:06:32,073
Okay, let me close this off,
145
145
00:06:32,930 --> 00:06:37,930
and now let's add a add to end, or add to tail method.
146
146
00:06:38,480 --> 00:06:40,070
I'll call it add to end.
147
147
00:06:40,070 --> 00:06:42,180
Now for this method, we have to set
148
148
00:06:42,180 --> 00:06:44,600
the previous field to point to the node
149
149
00:06:44,600 --> 00:06:46,410
that's currently at the end of the list.
150
150
00:06:46,410 --> 00:06:48,740
Remember, we're gonna have a node that's pointed
151
151
00:06:48,740 --> 00:06:52,220
to by tail, and we wanna insert a node at the end,
152
152
00:06:52,220 --> 00:06:55,040
so we want tail to point to the new node,
153
153
00:06:55,040 --> 00:06:57,860
and we want the new node's previous field
154
154
00:06:57,860 --> 00:07:00,810
to point to whatever the current tail is.
155
155
00:07:00,810 --> 00:07:02,810
Now, once again, we also have to worry about
156
156
00:07:02,810 --> 00:07:06,270
whether we're trying to add to the end of an empty list
157
157
00:07:06,270 --> 00:07:09,200
because if we are, we're gonna want to set the head
158
158
00:07:09,200 --> 00:07:11,840
to the new node just like in the add to front
159
159
00:07:11,840 --> 00:07:13,510
if we were inserting into an empty list
160
160
00:07:13,510 --> 00:07:15,633
we wanted to set the tail to the new node.
161
161
00:07:17,630 --> 00:07:20,753
So we'll say public void addToEnd,
162
162
00:07:21,730 --> 00:07:23,543
and again, we want the employee,
163
163
00:07:26,340 --> 00:07:29,073
and so we'll create a new node as we've done before.
164
164
00:07:36,106 --> 00:07:39,430
And now we want to test whether we have an empty list or not
165
165
00:07:39,430 --> 00:07:42,870
so we'll say if, and it doesn't really matter here
166
166
00:07:42,870 --> 00:07:44,560
if we test head or tail.
167
167
00:07:44,560 --> 00:07:47,500
Since we're in the add to end method, we'll test tail.
168
168
00:07:47,500 --> 00:07:49,193
So if tail equals null,
169
169
00:07:50,110 --> 00:07:55,110
we want to set the head to the new node, and don't worry,
170
170
00:07:55,390 --> 00:07:58,080
we'll take care of the tail field in a minute.
171
171
00:07:58,080 --> 00:08:03,080
Otherwise, we wanna set the current tail's next field
172
172
00:08:04,170 --> 00:08:07,890
to the node we're adding, and we wanna set
173
173
00:08:07,890 --> 00:08:11,550
the previous field of the node we're adding
174
174
00:08:11,550 --> 00:08:13,223
to what used to be the tail.
175
175
00:08:14,080 --> 00:08:16,790
So if we have let's say just Jane in the list,
176
176
00:08:16,790 --> 00:08:19,860
and we're adding John, and we're adding John to the end,
177
177
00:08:19,860 --> 00:08:22,250
we're gonna want Jane, the current tail,
178
178
00:08:22,250 --> 00:08:23,550
we're gonna want her next field
179
179
00:08:23,550 --> 00:08:26,090
to point to John who is the new node,
180
180
00:08:26,090 --> 00:08:28,510
and we're gonna want John's previous field
181
181
00:08:28,510 --> 00:08:30,680
to point to Jane, and she's currently the tail
182
182
00:08:30,680 --> 00:08:32,580
'cause we haven't changed the tail yet,
183
183
00:08:32,580 --> 00:08:33,740
and that's what we're gonna do now.
184
184
00:08:33,740 --> 00:08:37,690
So our final step is to set the tail to node,
185
185
00:08:37,690 --> 00:08:40,370
and of course we need to increment the size.
186
186
00:08:40,370 --> 00:08:43,760
And so this adds an employee to the end.
187
187
00:08:43,760 --> 00:08:45,680
So let's go back to the main method,
188
188
00:08:45,680 --> 00:08:48,593
and let's add Bill to the end of our list.
189
189
00:08:52,904 --> 00:08:55,850
Let me create the employee instance separately
190
190
00:08:55,850 --> 00:09:00,850
so I'll say Employee billEnd to show that we want him
191
191
00:09:01,510 --> 00:09:06,510
at the end, equals new Employee Bill, End,
192
192
00:09:06,750 --> 00:09:09,483
and we'll give him an ID of 78,
193
193
00:09:11,090 --> 00:09:13,753
and then we'll say list.addToEnd, billEnd,
194
194
00:09:17,340 --> 00:09:19,000
and I'll call copy these two lines.
195
195
00:09:19,000 --> 00:09:20,950
We'll print our list, and we'll print the size
196
196
00:09:20,950 --> 00:09:23,883
just to make that we're incrementing the size correctly.
197
197
00:09:24,840 --> 00:09:26,113
All right, let's run.
198
198
00:09:30,380 --> 00:09:33,260
And now we'll see we have five employees,
199
199
00:09:33,260 --> 00:09:36,030
and this time, Bill is not at the front of the list
200
200
00:09:36,030 --> 00:09:37,550
because that's not where we've added him.
201
201
00:09:37,550 --> 00:09:40,240
So we've got Mike, Mary.
202
202
00:09:40,240 --> 00:09:42,110
So far, our list is the same.
203
203
00:09:42,110 --> 00:09:43,233
John Doe,
204
204
00:09:44,420 --> 00:09:49,260
Jane Jones, and finally we have Bill end at the very end,
205
205
00:09:49,260 --> 00:09:50,993
so he's where he's supposed to be.
206
206
00:09:52,170 --> 00:09:53,600
I'll just close this down,
207
207
00:09:53,600 --> 00:09:56,020
and let's go back to our link list class.
208
208
00:09:56,020 --> 00:09:58,970
Now just as in the add to front method,
209
209
00:09:58,970 --> 00:10:00,970
we didn't have to worry about setting the new nodes
210
210
00:10:00,970 --> 00:10:04,510
previous field 'cause it would be initialised to null.
211
211
00:10:04,510 --> 00:10:06,700
In the add to end method, we don't have to worry
212
212
00:10:06,700 --> 00:10:08,830
about setting the new node's next field
213
213
00:10:08,830 --> 00:10:10,670
because it's initialised to null.
214
214
00:10:10,670 --> 00:10:13,840
Okay, so now let's look at removing items.
215
215
00:10:13,840 --> 00:10:17,850
So we have a remove from front method at the moment,
216
216
00:10:17,850 --> 00:10:19,480
and now we have to do a bit more work
217
217
00:10:19,480 --> 00:10:21,110
because we have to worry about the tail,
218
218
00:10:21,110 --> 00:10:23,600
and we have to worry about the previous field
219
219
00:10:23,600 --> 00:10:27,650
in whatever node comes after the head.
220
220
00:10:27,650 --> 00:10:30,930
Now it's possible we're going to be removing the only node
221
221
00:10:30,930 --> 00:10:34,350
in the list, so we have to handle that special case.
222
222
00:10:34,350 --> 00:10:35,970
So basically what do we wanna do?
223
223
00:10:35,970 --> 00:10:39,450
Let's suppose that we just have John and Jane in the list,
224
224
00:10:39,450 --> 00:10:40,760
and John is at the front.
225
225
00:10:40,760 --> 00:10:43,480
So when we take John away, Jane's next field
226
226
00:10:43,480 --> 00:10:46,090
will not change, so we don't have to worry about that,
227
227
00:10:46,090 --> 00:10:48,040
but her previous field has to change,
228
228
00:10:48,040 --> 00:10:52,640
and she wants to point to whatever came before John,
229
229
00:10:52,640 --> 00:10:55,670
and so she'll wanna point to John's previous field
230
230
00:10:55,670 --> 00:10:57,790
because we're gonna take John out,
231
231
00:10:57,790 --> 00:11:00,240
so whatever was previously before John
232
232
00:11:00,240 --> 00:11:02,490
will now be before Jane.
233
233
00:11:02,490 --> 00:11:04,950
Now, if we're removing from the front, that'll be null,
234
234
00:11:04,950 --> 00:11:08,210
so we could explicitly set her field to null, or we
235
235
00:11:08,210 --> 00:11:11,520
could just set her to whatever John's previous field has.
236
236
00:11:11,520 --> 00:11:13,440
And then we want to move the head,
237
237
00:11:13,440 --> 00:11:16,390
and so we'll set the head to Jane, and that's it.
238
238
00:11:16,390 --> 00:11:19,150
If we want, we can clean up the references.
239
239
00:11:19,150 --> 00:11:22,250
In John's nodes, we could set his next reference to null
240
240
00:11:22,250 --> 00:11:23,700
just like we're already doing,
241
241
00:11:23,700 --> 00:11:27,040
but essentially what we really have to handle here
242
242
00:11:27,040 --> 00:11:31,420
on top of what we're already doing is Jane's previous field.
243
243
00:11:31,420 --> 00:11:34,470
Now, if John is the only node in the list,
244
244
00:11:34,470 --> 00:11:37,150
then we're gonna have to worry about updating the tail
245
245
00:11:37,150 --> 00:11:39,500
because the tail will now become null.
246
246
00:11:39,500 --> 00:11:41,760
If John isn't the only node in the list,
247
247
00:11:41,760 --> 00:11:43,420
we don't have to change the tail.
248
248
00:11:43,420 --> 00:11:45,300
The tail's gonna stay the same 'cause we're taking
249
249
00:11:45,300 --> 00:11:47,040
the front node off the list,
250
250
00:11:47,040 --> 00:11:49,710
and so if he isn't the only node in the list,
251
251
00:11:49,710 --> 00:11:51,090
the tail isn't gonna change.
252
252
00:11:51,090 --> 00:11:53,900
It's still gonna be pointing to the last node in the list.
253
253
00:11:53,900 --> 00:11:58,900
Okay, so after we've saved off the node we're removing
254
254
00:11:59,050 --> 00:12:01,720
into remove node, we're gonna test
255
255
00:12:01,720 --> 00:12:05,000
to see if we're removing the only node in the list,
256
256
00:12:05,000 --> 00:12:09,810
and we'll do that by saying if head.getNext equals null
257
257
00:12:13,197 --> 00:12:17,472
because if the head node, if the next field in the head node
258
258
00:12:17,472 --> 00:12:20,610
is null, it means we've only got one node in the list
259
259
00:12:20,610 --> 00:12:22,840
so we're removing the only node, and so in that case,
260
260
00:12:22,840 --> 00:12:24,940
we have to worry setting the tail to null.
261
261
00:12:27,520 --> 00:12:30,680
If we're not removing the only node in the list,
262
262
00:12:30,680 --> 00:12:34,200
then we're going to handle Jane's previous field,
263
263
00:12:34,200 --> 00:12:36,420
and so we're gonna say head.getNext
264
264
00:12:36,420 --> 00:12:39,870
because if Jane's the second node in the list,
265
265
00:12:39,870 --> 00:12:42,240
John's next field is pointing to her,
266
266
00:12:42,240 --> 00:12:44,900
so that's head.getNext, so this will return Jane,
267
267
00:12:44,900 --> 00:12:47,380
and we wanna set her previous field to null.
268
268
00:12:47,380 --> 00:12:50,210
We could set this to head.getPrevious
269
269
00:12:50,210 --> 00:12:53,330
but because we know we're removing from the front,
270
270
00:12:53,330 --> 00:12:55,060
we'll just ahead and set it to null,
271
271
00:12:55,060 --> 00:12:57,280
and then we do what we did before.
272
272
00:12:57,280 --> 00:13:00,940
We set the head to head.getNext 'cause that's Jane,
273
273
00:13:00,940 --> 00:13:02,640
and we decrement the size,
274
274
00:13:02,640 --> 00:13:05,260
and here we're just cleaning up a reference.
275
275
00:13:05,260 --> 00:13:07,230
We don't have to do that but we're cleaning it up,
276
276
00:13:07,230 --> 00:13:08,650
and then we return the node.
277
277
00:13:08,650 --> 00:13:10,240
So let's go back to our main method,
278
278
00:13:10,240 --> 00:13:12,180
and let's remove from the front of the list,
279
279
00:13:12,180 --> 00:13:14,403
so we'll say list.removeFromFront.
280
280
00:13:16,090 --> 00:13:17,400
We don't have to pass anything
281
281
00:13:17,400 --> 00:13:20,210
'cause we're taking off the first person in the list.
282
282
00:13:20,210 --> 00:13:23,683
And we'll print out our list, and the size again.
283
283
00:13:26,070 --> 00:13:27,093
So let's run.
284
284
00:13:30,060 --> 00:13:32,130
So we're back to four employees,
285
285
00:13:32,130 --> 00:13:35,530
and now Mary is the first employee on the list.
286
286
00:13:35,530 --> 00:13:36,483
Mike is gone.
287
287
00:13:37,660 --> 00:13:40,340
And so if we go to the end, Bill's still at the end.
288
288
00:13:40,340 --> 00:13:41,380
We didn't touch him,
289
289
00:13:41,380 --> 00:13:44,750
and we have one fewer employees than we did before.
290
290
00:13:44,750 --> 00:13:49,750
Okay, so we have methods for adding to the front
291
291
00:13:49,990 --> 00:13:51,660
of the list, adding to the end of the list,
292
292
00:13:51,660 --> 00:13:53,620
removing from the front, so I guess we need
293
293
00:13:53,620 --> 00:13:57,780
a remove from end method, so let's write that now.
294
294
00:13:57,780 --> 00:14:00,997
Public EmployeeNode, removeFromEnd.
295
295
00:14:02,970 --> 00:14:04,230
We don't need to pass anything
296
296
00:14:04,230 --> 00:14:06,290
'cause we're always removing the last node.
297
297
00:14:06,290 --> 00:14:08,400
What do we wanna do when we remove from the end?
298
298
00:14:08,400 --> 00:14:11,960
Well, right now we have Jane at the end, let's say,
299
299
00:14:11,960 --> 00:14:14,640
and then Bill, and we wanna remove Bill,
300
300
00:14:14,640 --> 00:14:17,520
so we're gonna have to change the tail
301
301
00:14:17,520 --> 00:14:20,260
because the tail is now going to become Jane,
302
302
00:14:20,260 --> 00:14:22,320
so in this case, we do have to worry
303
303
00:14:22,320 --> 00:14:24,150
about changing the tail,
304
304
00:14:24,150 --> 00:14:28,980
and we're gonna want to set Jane's next field to null
305
305
00:14:28,980 --> 00:14:31,100
because now she'll be the end of list.
306
306
00:14:31,100 --> 00:14:32,040
And if we wanted to,
307
307
00:14:32,040 --> 00:14:34,250
we can clean up Bill's previous field.
308
308
00:14:34,250 --> 00:14:37,360
Now if Bill is the only one in the list,
309
309
00:14:37,360 --> 00:14:40,130
we also have to worry about setting head to null
310
310
00:14:40,130 --> 00:14:42,090
because if Bill is the only node in the list,
311
311
00:14:42,090 --> 00:14:44,070
so we remove him and there's an empty list,
312
312
00:14:44,070 --> 00:14:45,710
then we have to set head back to null,
313
313
00:14:45,710 --> 00:14:47,590
so we're gonna have to check for that case,
314
314
00:14:47,590 --> 00:14:48,930
but the very first thing we're gonna do
315
315
00:14:48,930 --> 00:14:51,529
is check for an empty list.
316
316
00:14:51,529 --> 00:14:53,940
I'll just copy this code.
317
317
00:14:53,940 --> 00:14:55,050
So if you have an empty list,
318
318
00:14:55,050 --> 00:14:57,270
we obviously don't have to do anything,
319
319
00:14:57,270 --> 00:14:58,700
nothing to remove.
320
320
00:14:58,700 --> 00:15:00,180
If we don't have an empty list,
321
321
00:15:00,180 --> 00:15:04,900
we'll say EmployeeNode, removedNode equals tail.
322
322
00:15:06,320 --> 00:15:09,460
So up here, the removed node was the head,
323
323
00:15:09,460 --> 00:15:11,680
but in remove from end, the remove node
324
324
00:15:11,680 --> 00:15:13,173
will obviously be the tail.
325
325
00:15:14,220 --> 00:15:16,140
And then we'll do the same thing we did up here,
326
326
00:15:16,140 --> 00:15:20,500
but this time I'll use if tail.getNext equals null because
327
327
00:15:20,500 --> 00:15:23,350
that would mean that this is the only node in the list.
328
328
00:15:23,350 --> 00:15:24,357
Now when we only have one node in the list,
329
329
00:15:24,357 --> 00:15:27,570
the head and the tail are both pointing to the same node.
330
330
00:15:27,570 --> 00:15:29,990
I used head here because we're removing from the front.
331
331
00:15:29,990 --> 00:15:32,460
I'll use tail here 'cause we're removing from the back,
332
332
00:15:32,460 --> 00:15:34,340
but essentially we're doing the same thing.
333
333
00:15:34,340 --> 00:15:37,963
So if tail.getNext equals null,
334
334
00:15:39,670 --> 00:15:43,210
then we only have one node in the list, and so in that case,
335
335
00:15:43,210 --> 00:15:48,210
we have to worry about setting the head to null.
336
336
00:15:48,900 --> 00:15:51,883
So you can kinda see we're doing the mirror image here.
337
337
00:15:53,160 --> 00:15:55,640
Here we had to worry about setting the tail to null
338
338
00:15:55,640 --> 00:15:59,250
'cause we set the head, we take care of the head here,
339
339
00:15:59,250 --> 00:16:01,870
and here we have to worry about setting the head to null.
340
340
00:16:01,870 --> 00:16:04,933
So if we have more than one node in the list,
341
341
00:16:05,780 --> 00:16:09,130
then what we wanna do here is the node that's becoming
342
342
00:16:09,130 --> 00:16:13,073
the new tail, we want to set their next field to null,
343
343
00:16:14,570 --> 00:16:16,980
and we can do that the same way we did up here.
344
344
00:16:16,980 --> 00:16:20,180
So we get tail.previousNode 'cause that's going
345
345
00:16:20,180 --> 00:16:22,150
to become the new tail,
346
346
00:16:22,150 --> 00:16:24,260
and then we'll set its next field to null.
347
347
00:16:24,260 --> 00:16:27,537
So we'll say tail.getPrevious.setNext to null.
348
348
00:16:31,280 --> 00:16:35,120
And so if we have the situation where we're removing Bill,
349
349
00:16:35,120 --> 00:16:37,050
and Jane is gonna become the new tail,
350
350
00:16:37,050 --> 00:16:39,330
well Bill is currently the tail
351
351
00:16:39,330 --> 00:16:41,490
'cause we haven't changed that yet.
352
352
00:16:41,490 --> 00:16:43,720
His previous field is pointing to Jane,
353
353
00:16:43,720 --> 00:16:46,380
and so her next field will now become null
354
354
00:16:46,380 --> 00:16:48,700
because she'll be the last node in the list.
355
355
00:16:48,700 --> 00:16:52,340
And then finally, we're gonna set the tail to
356
356
00:16:55,330 --> 00:16:56,270
tail.getPrevious
357
357
00:16:58,330 --> 00:17:02,080
because the new tail is now going to be Jane,
358
358
00:17:02,080 --> 00:17:05,150
and so right now, tail is pointing to Bill.
359
359
00:17:05,150 --> 00:17:06,960
His previous is pointing to Jane,
360
360
00:17:06,960 --> 00:17:10,743
and so the new tail becomes Bill, basically, .getPrevious.
361
361
00:17:12,890 --> 00:17:14,630
And now we'll do what did here,
362
362
00:17:14,630 --> 00:17:16,853
so I'll copy these lines of code.
363
363
00:17:18,650 --> 00:17:20,450
We wanna decrement the size.
364
364
00:17:20,450 --> 00:17:23,220
This time, we want to remove node's previous
365
365
00:17:24,380 --> 00:17:26,780
field to be set to null to clean that up,
366
366
00:17:26,780 --> 00:17:28,460
and then we return the remove node.
367
367
00:17:28,460 --> 00:17:30,830
So these two methods
368
368
00:17:30,830 --> 00:17:32,810
are kind of mirror images of each other.
369
369
00:17:32,810 --> 00:17:35,470
In one case, we're more concerned with what's going
370
370
00:17:35,470 --> 00:17:37,850
on at the head obviously, and in the other case,
371
371
00:17:37,850 --> 00:17:40,410
we're more concerned with what's going on at the tail.
372
372
00:17:40,410 --> 00:17:42,810
In this case, we have to worry about the tail
373
373
00:17:42,810 --> 00:17:45,440
only when we're removing the only node in the list,
374
374
00:17:45,440 --> 00:17:47,700
and in this case, we have to worry about the head
375
375
00:17:47,700 --> 00:17:49,900
if we're removing the only node in the list.
376
376
00:17:49,900 --> 00:17:52,330
Otherwise, we're just worrying about the tail.
377
377
00:17:52,330 --> 00:17:54,710
when we're removing from end, and we're just worrying
378
378
00:17:54,710 --> 00:17:57,010
about the head when we're removing from front.
379
379
00:17:58,430 --> 00:18:00,180
And if you look at these two methods,
380
380
00:18:00,180 --> 00:18:01,593
it's kind of the same thing.
381
381
00:18:02,890 --> 00:18:04,060
They're a little bit different
382
382
00:18:04,060 --> 00:18:05,880
but we could have written them similarly.
383
383
00:18:05,880 --> 00:18:07,550
In this case, in the add to front,
384
384
00:18:07,550 --> 00:18:10,730
we're always setting the next field of the node
385
385
00:18:10,730 --> 00:18:12,270
to whatever's at the head,
386
386
00:18:12,270 --> 00:18:14,340
and in the add to end, we're only doing that
387
387
00:18:14,340 --> 00:18:17,010
if we're dealing with a list that's not empty,
388
388
00:18:17,010 --> 00:18:20,150
so if we're adding the node into a list that isn't empty,
389
389
00:18:20,150 --> 00:18:21,530
because when you think about it,
390
390
00:18:21,530 --> 00:18:24,440
if the list is empty, this statement here
391
391
00:18:24,440 --> 00:18:27,690
is just gonna set the next field to null,
392
392
00:18:27,690 --> 00:18:30,710
and we don't really need to do that because the node's
393
393
00:18:30,710 --> 00:18:33,980
next field is initialised so we could do this.
394
394
00:18:33,980 --> 00:18:36,000
We could take this statement here
395
395
00:18:36,000 --> 00:18:38,200
and do the same thing that we're doing here,
396
396
00:18:39,770 --> 00:18:42,280
and only worry about setting the next field
397
397
00:18:42,280 --> 00:18:44,890
if we're dealing with a list that isn't empty
398
398
00:18:44,890 --> 00:18:47,560
so that there's already nodes in it, and so yeah,
399
399
00:18:47,560 --> 00:18:50,380
when we add the new node into the list,
400
400
00:18:50,380 --> 00:18:52,960
we'll worry about setting the next field.
401
401
00:18:52,960 --> 00:18:54,890
Otherwise the next field is already set.
402
402
00:18:54,890 --> 00:18:57,730
So now they're mirror images of each other.
403
403
00:18:57,730 --> 00:19:01,610
And let's run to see if everything's working.
404
404
00:19:01,610 --> 00:19:03,790
Before we do that, let's go back to main,
405
405
00:19:03,790 --> 00:19:06,840
and let's remove an item from the end of the list.
406
406
00:19:06,840 --> 00:19:10,593
So I'm gonna copy these three lines.
407
407
00:19:13,560 --> 00:19:15,323
I'm gonna say remove from end,
408
408
00:19:17,019 --> 00:19:18,233
and let's run.
409
409
00:19:21,690 --> 00:19:25,250
All right, so we started off with adding four employees,
410
410
00:19:25,250 --> 00:19:28,820
and we have Mike Wilson, Mary Smith, John Doe,
411
411
00:19:28,820 --> 00:19:31,860
and Jane Jones, and we have four employees in the list,
412
412
00:19:31,860 --> 00:19:36,150
then we added up here.
413
413
00:19:36,150 --> 00:19:39,670
We added Bill to the end, so now we have five employees,
414
414
00:19:39,670 --> 00:19:43,113
and we have Bill right at the end,
415
415
00:19:44,290 --> 00:19:47,670
and then we removed the first employee from the front
416
416
00:19:47,670 --> 00:19:50,830
so we're back down to four employees, and Mike is gone,
417
417
00:19:50,830 --> 00:19:54,610
and now finally, we removed an employee from the end,
418
418
00:19:54,610 --> 00:19:56,370
so we're down to three employees,
419
419
00:19:56,370 --> 00:19:58,370
and obviously something went wrong here.
420
420
00:19:58,370 --> 00:20:00,610
So let's go back to our code.
421
421
00:20:00,610 --> 00:20:02,290
Let me shut this down.
422
422
00:20:02,290 --> 00:20:03,990
Can you spot the error?
423
423
00:20:03,990 --> 00:20:07,740
Right here, we said if tail.getNext equals null.
424
424
00:20:07,740 --> 00:20:11,300
Well, the next field of the tail is always going to be null,
425
425
00:20:11,300 --> 00:20:13,680
and so what happened is we set the head to null,
426
426
00:20:13,680 --> 00:20:16,280
and that's why if I go back to thing here,
427
427
00:20:16,280 --> 00:20:18,810
our head basically blew away our list here.
428
428
00:20:18,810 --> 00:20:22,433
So this should be if tail.getPrevious equals null,
429
429
00:20:24,740 --> 00:20:27,940
then we know we only have one node in the list.
430
430
00:20:27,940 --> 00:20:29,763
Let's run that again.
431
431
00:20:31,680 --> 00:20:33,910
All right, this time we didn't blow our list away.
432
432
00:20:33,910 --> 00:20:36,330
So we went through the first results,
433
433
00:20:36,330 --> 00:20:38,430
and then finally back here,
434
434
00:20:38,430 --> 00:20:40,840
we wanted to remove Bill from the end,
435
435
00:20:40,840 --> 00:20:45,840
so we have Mary Smith, John Doe, and Jane Jones,
436
436
00:20:46,240 --> 00:20:48,550
and we removed Bill from the end,
437
437
00:20:48,550 --> 00:20:51,330
and we have three employees.
438
438
00:20:51,330 --> 00:20:55,110
And so our code is working once we fixed that bug.
439
439
00:20:55,110 --> 00:20:57,380
If you only have one node in the list,
440
440
00:20:57,380 --> 00:20:59,580
then tail and head are pointing at the same thing,
441
441
00:20:59,580 --> 00:21:02,850
but obviously if you don't have just one node in the list,
442
442
00:21:02,850 --> 00:21:06,740
then we wanna be testing the previous field for the tail
443
443
00:21:06,740 --> 00:21:09,650
'cause we wanna know if there's anything before the tail
444
444
00:21:09,650 --> 00:21:12,010
because there's never going to be anything after the tail,
445
445
00:21:12,010 --> 00:21:15,003
so that's why we blew our list away here.
446
446
00:21:16,650 --> 00:21:19,760
Here we wanna use get next because, in that case,
447
447
00:21:19,760 --> 00:21:21,510
there's never anything before the head,
448
448
00:21:21,510 --> 00:21:23,550
so we've gotta check what comes after.
449
449
00:21:23,550 --> 00:21:27,340
Okay, so that's it for a simple implementation
450
450
00:21:27,340 --> 00:21:28,360
of a doubly linked list.
451
451
00:21:28,360 --> 00:21:29,750
I just wanted to give you some idea
452
452
00:21:29,750 --> 00:21:31,880
of what's going on under the covers.
453
453
00:21:31,880 --> 00:21:34,950
Now, as I mentioned a few videos ago,
454
454
00:21:34,950 --> 00:21:37,660
the JDK has a link-list class,
455
455
00:21:37,660 --> 00:21:39,420
so if you wanna use a link list,
456
456
00:21:39,420 --> 00:21:42,500
you're probably going to use the class in the JDK,
457
457
00:21:42,500 --> 00:21:43,660
and so in the next video,
458
458
00:21:43,660 --> 00:21:45,780
we'll take a quick look at that class.
459
459
00:21:45,780 --> 00:21:46,773
I'll see you there.
41225
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.