Doubly linked list with head/tail references for int values (Task 1) and a generic LinkedList<T>/ListNode<T> version (Task 2). Both implement add, get, remove, getSize with O(n/2) walks via the closer-end heuristic. Includes IntLinkedListTest covering empty, single-element, head/tail/middle removal, and out-of-bounds cases. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
110 lines
2.9 KiB
Java
110 lines
2.9 KiB
Java
public class IntLinkedList {
|
|
private IntListNode headNode;
|
|
private IntListNode tailNode;
|
|
private int size;
|
|
public IntLinkedList() {
|
|
headNode = null;
|
|
tailNode = null;
|
|
size = 0;
|
|
}
|
|
public void add(int value) {
|
|
if (headNode == null) {
|
|
headNode = new IntListNode(value, null, null);
|
|
tailNode = headNode;
|
|
|
|
}
|
|
else {
|
|
|
|
IntListNode newNode = new IntListNode(value, null, null);
|
|
newNode.prevNode = tailNode;
|
|
tailNode.nextNode = newNode;
|
|
tailNode = newNode;
|
|
}
|
|
size++;
|
|
}
|
|
public int getSize() {
|
|
return size;
|
|
}
|
|
public int get(int index){
|
|
if (index < 0 || index > (size - 1)){
|
|
throw new IllegalArgumentException("Index Out of Bounds");
|
|
}
|
|
if (index < size/2){
|
|
int pos = 0;
|
|
IntListNode curNode = headNode;
|
|
while (pos < index){
|
|
curNode = curNode.nextNode;
|
|
pos++;
|
|
}
|
|
return curNode.value;
|
|
}
|
|
else {
|
|
int pos = size - 1;
|
|
IntListNode curNode = tailNode;
|
|
while (pos > index){
|
|
curNode = curNode.prevNode;
|
|
pos --;
|
|
}
|
|
return curNode.value;
|
|
}
|
|
}
|
|
|
|
public void remove(int index){
|
|
if (index < 0 || index > (size - 1)){
|
|
throw new IllegalArgumentException("Index Out of Bounds");
|
|
}
|
|
if(index == 0){
|
|
if(size == 1){
|
|
headNode = null;
|
|
tailNode = null;
|
|
}
|
|
else {
|
|
headNode = headNode.nextNode;
|
|
headNode.prevNode = null;
|
|
}
|
|
size --;
|
|
return;
|
|
}
|
|
if (index == (size - 1)){
|
|
|
|
tailNode = tailNode.prevNode;
|
|
tailNode.nextNode = null;
|
|
size --;
|
|
return;
|
|
}
|
|
|
|
if (index < size/2){
|
|
int pos = 0;
|
|
IntListNode curNode = headNode;
|
|
while (pos < index){
|
|
curNode = curNode.nextNode;
|
|
pos++;
|
|
}
|
|
// Set the prev of the following node so pos +1
|
|
curNode.nextNode.prevNode = curNode.prevNode;
|
|
|
|
// Then set the next of the previous node;
|
|
curNode.prevNode.nextNode = curNode.nextNode;
|
|
|
|
size--;
|
|
|
|
}
|
|
else {
|
|
int pos = size - 1;
|
|
IntListNode curNode = tailNode;
|
|
while (pos > index){
|
|
curNode = curNode.prevNode;
|
|
pos --;
|
|
}
|
|
// Set the prev of the following node so pos +1
|
|
curNode.nextNode.prevNode = curNode.prevNode;
|
|
|
|
// Then set the next of the previous node;
|
|
curNode.prevNode.nextNode = curNode.nextNode;
|
|
|
|
size--;
|
|
}
|
|
}
|
|
|
|
|
|
} |