Lets start where we left off in the last post.
Add a function that removes nodes from the end of our linked list. Here’s what our function definition looks like:
Before we get into writing the function itself, consider our use cases:
Here’s how we will handle each case:
Add code to handle a removing from an empty list. We will check for a null head and return null if found:
Next add code to declare our result, return our result, and decrement the size of our list:
T result;
//add code to the get correct result and remove the node from the list here
size--;
return result;
Next add our if statement to handle the 2nd and 3rd use cases. By checking if head.next is equal to null we will know if our list has a size of 1 or a size of greater then one:
if(head.next == null) {
//add code to handle use case 2 here
} else {
//add code to handle use case 3 here
}
Add code to handle a list of size one. For this case the result is the data contained within the head of the list (the only node in the list). After getting the result we set the head to null to remove the node:
Add code to handle a list of size > one. We need to first declare a node n that represents the node to remove. We also need to declare a node prev that represents the node before the node to remove in the list. To start with n will be equal to head.next and prev will be equal to head. We know that both n and prev will not be equal to null since we have checked for those conditions already in our function.
Iterate through the linked list. At each step we declare set both n and prev to the next node in the list. At the end of this while loop the n will be equal to the last node in the list and prev will be equal to the node before the last node in the list.
Now that the n and prev nodes are set correctly we can remove the last node from our list by declaring prev.next to be equal to null. We also update our result to be equal to the data in the node removed.
The completed remove function looks as follows:
public T remove() {
if(head == null)
return null;
T result;
if(head.next == null) {
result = head.data;
head = null;
} else {
Node<T> n = head.next;
Node<T> prev = head;
while(n.next != null) {
n = n.next;
prev = prev.next;
}
prev.next = null;
result = n.data;
}
size--;
return result;
}
Add a function that returns the element at a specified position in the list. The function definition looks as follows:
Consider the use cases of our function:
Here’s how we will handle each use case:
If the index is negative return null:
If the list is empty (head is equal to null) return null:
If the index is equal to zero return the data in the head of the list. Also return null if we get the end of our function without finding the index (ie index >= size):
if(index == 0)
return head.data;
//add code to get the data at the correct position here
return null;
Declare our position to be zero (the start of the list) and a node n to refer to the current node in the list. N will be initialized to head.next:
Iterate through our list for each element increment our position by one. If our position becomes equal to the index we are looking for break out of our for loop. We want our position to be the index of the element contained in n:
Finally after the while loop if our position and index are equal then return the data in n:
The return null statement added earlier will handle the case if the position is not contained within the list (ie index >= size).
The completed function looks as follows:
public T get(int index) {
if(index < 0)
return null;
if(head == null)
return null;
if(index == 0)
return head.data;
int position = 0;
Node<T> n = head.next;
while(n != null) {
position++;
if(position == index)
break;
n = n.next;
}
if(position == index)
return n.data;
return null;
}
We’ll continue the implementation of our linked list in Implementing a Linked List in Java - Part Three