Implementing SortedLinkedList
SortedLinkedList<T> implements SortedList<T> with two sentinel nodes, head and tail, that hold no user value. An empty list is the two sentinels pointing at each other; the real nodes between them are always kept in ascending order.
public class SortedLinkedList<T extends Comparable<T>> implements SortedList<T> {
private Node<T> head; // front sentinel
private Node<T> tail; // back sentinel
private int size; // number of real nodes
private static class Node<T> {
T value;
Node<T> next;
Node<T> prev;
Node(T value) {
this.value = value;
}
}
public SortedLinkedList() {
head = new Node<>(null);
tail = new Node<>(null);
head.next = tail;
tail.prev = head;
size = 0;
}
public int size() {
return size;
}
private Node<T> insertBetween(T value, Node<T> before, Node<T> after) {
Node<T> node = new Node<>(value);
node.prev = before;
node.next = after;
before.next = node;
after.prev = node;
size++;
return node;
}
// add and remove go here
}
Solution
public void add(T value) {
if (value == null) {
throw new NullPointerException();
}
Node<T> current = head.next;
while (current != tail && current.value.compareTo(value) <= 0) {
current = current.next;
}
insertBetween(value, current.prev, current);
}
: the traversal steps through up to all real nodes to find the first value greater than value, and the splice itself is .
Solution
public boolean remove(T value) {
Node<T> current = head.next;
while (current != tail) {
if (Objects.equals(current.value, value)) {
current.prev.next = current.next;
current.next.prev = current.prev;
size--;
return true;
}
current = current.next;
}
return false;
}
: the traversal steps through up to all real nodes looking for a match, and unlinking the matched node is .